TypeDescriptor属性检索不一致

时间:2014-04-03 17:09:26

标签: c# typedescriptor

我在玩System.ComponentModel.TypeDescriptor时发现了一些有趣的东西:

public class Person
{
    public string Name { get; set; }

    public int Age { get; set; }

    public DateTime DateOfBirth { get; set; }

    public Enum Enum { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var person = new Person();

        var typeDescriptionProvider = TypeDescriptor.AddAttributes(person, new DescriptionAttribute("Some description of this person"));

        // Returns no attributes if person is a *struct* instance,
        // but does return the DescriptionAttribute if person is a *class* instance
    --> var descriptionAttributes = TypeDescriptor.GetAttributes(person).OfType<DescriptionAttribute>().ToList();

        // Always returns the DescriptionAttribute
        var descriptionAttributesUsingTdp = typeDescriptionProvider.GetTypeDescriptor(person).GetAttributes().OfType<DescriptionAttribute>().ToList();

        Console.ReadLine();
    }
}

Person的定义是一个类时,-->的代码行找到并返回DescriptionAttribute就好了。

当我将Person更改为结构时,代码找不到DescriptionAttribute

Why?

这种差异背后的理由是什么?对于值类型缺少的引用类型,是否存在一些魔力?

我知道-->下面的代码行返回属性,无论Person的实例是类还是结构。这是因为the TypeDescriptionProvider returned by the AddAttributes() method call was the one that performed the addition

1 个答案:

答案 0 :(得分:3)

TypeDescriptor.GetAttributes(person)是结构时,为什么没有Person返回属性?

TypeDescriptor.AddAttributesTypeDescriptor.GetAttributes使用引用相等来查找TypeDescriptor内部缓存中的对象。如果Person是一个类,则这两个方法调用中的person参数引用相同的实例。但是,如果Person是一个结构,那么person参数将被独立地加载到不同的实例中,因此GetAttributes无法找到原始的person }。

如果person仅被装箱一次,则代码按预期工作:

object person = new Person();  // `object` instead of `var`

为什么typeDescriptionProvider.GetTypeDescriptor(person).GetAttributes()始终返回属性?

TypeDescriptionProvider.GetTypeDescriptor(Object)文档不清楚(至少对我来说),但请注意,您显然可以将任何传递给typeDescriptionProvider.GetTypeDescriptor - 例如{{1} (一个结构)或42(一个类) - 并返回你的属性:

"Hello, World!"

基于此行为,我的猜测是var descriptionAttributesUsingTdp = typeDescriptionProvider.GetTypeDescriptor(42) .GetAttributes().OfType<DescriptionAttribute>().ToList(); // descriptionAttributesUsingTdp.Count == 1 返回的typeDescriptionProviderTypeDescriptor.AddAttributes(person, ...)无关。相反,它代表一个插件,可以将您的属性添加到任何对象,而person是执行此操作的方法。