为什么GetCustomAttributes返回的是object[]而不是Attribute[]?

12
只是好奇,看到MemberInfo.GetCustomAttributes。这是否暗示它可能包含一个非属性对象?
3个回答

11
这是因为CLI规范并未强制要求属性派生自Attribute类。规范在II Part 21(第225页)中声明:
“虽然任何用户定义的类型都可以用作属性,但CLS兼容性要求属性是System.Attribute基类的实例。 CLI预定义了一些属性类型并使用它们来控制运行时行为。一些语言预定义属性类型以表示在CTS中没有直接表示的语言特性。用户或其他工具可以定义和使用其他属性类型。”
基本上,CLR本身无法保证结果将是Attribute - 这仅适用于CLS兼容的语言。非CLS兼容的语言允许具有任何类型的属性,这意味着ICustomAttributeProvider.GetCustomAttributes(涉及的实现接口)需要提供一种机制来获取非Attribute派生的属性。

2
除了Reed上面所说的之外,MemberInfo.GetCustomAttributes API允许您指定一个过滤器类型,影响返回的数组类型。也就是说,当您指定typeof(MyAttribute)时,结果实际上将是一个MyAttribute[](强制转换为object[])。
现在,当您指定一个接口类型IMyAttribute时,该数组的类型为IMyAttribute[]。虽然可以将IMyAttribute[]强制转换为object[],但无法将其强制转换为Attribute[]。因此,从本质上讲,如果结果是Attribute[],则基于接口的过滤将不起作用。
(顺便说一句,更新的Attribute.GetCustomAttributes API - 修复了属性和事件的继承解析 - 其返回类型为Attribute[]。这使得基于接口的过滤成为不可能;尝试传入一个接口类型进行过滤时会引发ArgumentException。)

使用 Attribute.GetCustomAttributes 可以避免额外的 ToArray() 调用。通过这些 API,通常可以避免这种情况的发生。 - l33t

0
根据MSDN:http://msdn.microsoft.com/en-us/library/kff8s254.aspx
This method ignores the inherit parameter for properties and events. 
To search the inheritance chain for attributes on properties and events, 
use the appropriate overloads of the Attribute.GetCustomAttributes method.

我的理解是,它允许你甚至可以自定义一个属性而不必继承自System.Attribute,完全编写你自己的“Attribute”,有了这种灵活性,你的“Attribute”有时只能继承Object。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接