惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
Spread Privacy
Spread Privacy
T
Threatpost
C
Cisco Blogs
P
Palo Alto Networks Blog
AI
AI
Cyberwarzone
Cyberwarzone
NISL@THU
NISL@THU
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
T
Tor Project blog
Latest news
Latest news
AWS News Blog
AWS News Blog
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
WordPress大学
WordPress大学
Vercel News
Vercel News
S
Securelist
爱范儿
爱范儿
J
Java Code Geeks
Know Your Adversary
Know Your Adversary
S
Schneier on Security
Hugging Face - Blog
Hugging Face - Blog
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
D
DataBreaches.Net
宝玉的分享
宝玉的分享
D
Darknet – Hacking Tools, Hacker News & Cyber Security
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
K
Kaspersky official blog
美团技术团队
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
量子位
博客园_首页
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
Google Online Security Blog
Google Online Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
T
Threat Research - Cisco Blogs
雷峰网
雷峰网
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed
S
Security Affairs

博客园 - 江南白衣

花开在眼前 多收了三五斗 SQL Server 2008 Spatial Tools Visual Studio 2008 Service Pack 1 Release View to Presenter Communication Composite Application Guidance - What is it? Unsaved Changes When CAB Application Closes: The Notification Pattern AddIn Enabled Applications 带套的日子 NET Debugger Visualizers List Composite Application Guidance for WPF-June 2008 Managed Extensibility Framework (MEF) Managed Extensibility and Add-In Framework 祝我生日快乐 Why use the Entity Framework? Entity Framework FAQ Visual Studio 2008 SP1: Sync Services for ADO.Net with SQL Server 2008 Change Tracking (转) Managed Services for Windows Mobile xUnit.net 1.0.1 Realese
Polymorphic Databinding Solutions
江南白衣 · 2008-08-02 · via 博客园 - 江南白衣

原文:http://www.ayende.com/Blog/archive/2006/07/25/7397.aspx

Let us assume that you have the following class hierarchy:

(Image from clipboard).png

Now, what do you think the result of this code will be?

BindingList<Animal> animals = new BindingList<Animal>();

animals.Add(new Dog());

animals.Add(new Cat());

GridView gridView = new GridView();

gridView.DataSource = animals;

gridView.DataBind();

Ten points goes to the lady on the right that said that it will produce the following error:

Unhandled Exception: System.Reflection.TargetInvocationException: Property accessor 'Name' on object 'AnimalDesc.Cat' threw the following exception:'Object does not match target type.' ---> System.Reflection.TargetException: Object does not match target type.

The reason for this bug is that the TypeDescriptors in .Net are not aware of polymorphism. Even though both Cat and Dog inherit from Animal and has a Name property, and that the list that I passed to the DataSource is BindingList<T>, the TypeDescriptor only looks at the first item in the list, and uses it to describe all types in the list. This can cause problems when the collection that you pass to the GridView contains an inheritance hierarchy.

After butting my head against this issue for too long, I finally came up with this solution:

public class AnimalTypeDescriptionProvider : TypeDescriptionProvider

{

    public AnimalTypeDescriptionProvider() 

        :base(TypeDescriptor.GetProvider(typeof(Animal)))

    {

    }

    public override Type GetReflectionType(Type objectType, object instance)

    {

        return base.GetReflectionType(typeof(Animal), instance);

    }

    public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)

    {

        return base.GetTypeDescriptor(typeof(Animal), instance);

    }

    public static void Register()

    {

        TypeDescriptor.AddProvider(new AnimalTypeDescriptionProvider(), typeof(Animal));

    }

}

Then, I call the AnimalTypeDescriptionProvider.Register(); method in the start of the application.

What this does is it lies to the data binding infrastructure, and tells them that any type that inherits from Animal is actually an Animal, and should be treated appropriately.

This solution is good enough for now, but it will prevent me from databinding a list of Dogs, for instance.