【问题标题】:TypeDescriptor Attribute Retrieval InconsistencyTypeDescriptor 属性检索不一致
【发布时间】:2014-05-15 16:23:46
【问题描述】:

我在玩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的定义是一个类时,带有--&gt;的那行代码找到并返回DescriptionAttribute就好了。

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

这种差异背后的原因是什么?值类型不存在的引用类型有什么魔力吗?

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

【问题讨论】:

  • 为我工作。您是否看到您发布的代码(以及public struct Person)的行为,或者您是否过度简化了问题(从而解决了它)?
  • 奇怪!我已经编辑了问题以包含问题的屏幕截图。为什么我会遇到这种情况?

标签: c# typedescriptor


【解决方案1】:

Person是结构体时,为什么TypeDescriptor.GetAttributes(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) 文档不清楚(至少对我而言),但请注意,您显然可以将 anything 传递给 typeDescriptionProvider.GetTypeDescriptor — 例如 42(结构)或 @987654341 @(一个类)——并取回你的属性:

var descriptionAttributesUsingTdp = typeDescriptionProvider.GetTypeDescriptor(42)
    .GetAttributes().OfType<DescriptionAttribute>().ToList();
// descriptionAttributesUsingTdp.Count == 1

基于这种行为,我的猜测是TypeDescriptor.AddAttributes(person, ...) 返回的typeDescriptionProviderperson 没有关联。相反,它表示一个插件,可以将您的属性添加到 any 对象,GetTypeDescriptor 就是这样做的方法。

【讨论】:

  • 感谢@MichaelLiu 精心研究的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 2017-06-14
  • 1970-01-01
  • 2014-01-11
  • 1970-01-01
  • 2012-10-13
相关资源
最近更新 更多