2010-01-27 85 views
18

C#属性在其名称中是否有“属性”(例如DataMemberAttribute),但没有使用此后缀进行初始化?例如:C#属性名称缩写

[DataMember] 
private int i; 
+0

我要说,问题是**如何**是可能的,还没有回答。但我相信它使用反射'X OR X +“属性”'来搜索名称。 – serhio 2010-01-27 10:22:25

+0

@serhio根据Anton Gogolev的说法,它是编译器提供的一个快捷方式。这对我来说足以作为答案(如果它是正确的)。它也适用于自定义属性。 – Fabiano 2010-01-27 10:30:13

+0

个人对我来说不是很清楚什么样的“捷径”可以提供一个编译器。 – serhio 2010-01-27 11:13:51

回答

19

按照C# Language Specification

按照约定,属性类的名称与Attribute后缀。 属性名称的形式类型名称可以包含或省略此后缀。

这是由C#编译器和决不是一个CLR特征提供的快捷方式。编译器对属性进行特殊处理的另一个示例是ObsoleteAttribute属性:这个属性强制编译器发出警告/错误,但它对CLR没有特殊含义。

至于如何解决属性,请参阅上面的链接。总结它:

如果一个属性类被发现有和没有这个后缀,存在歧义,并且编译时错误结果。如果attribute-name拼写为使其最右侧的标识符为verbatim identifier,那么只有没有后缀的属性才会匹配,从而可以解决此类歧义问题。

“逐字标识符”是一个带有@前缀的标识符。

与MSDN继续:

using System; 

[AttributeUsage(AttributeTargets.All)] 
public class X: Attribute 
{} 

[AttributeUsage(AttributeTargets.All)] 
public class XAttribute: Attribute 
{} 

[X]     // Error: ambiguity 
class Class1 {} 

[XAttribute]   // Refers to XAttribute 
class Class2 {} 

[@X]     // Refers to X 
class Class3 {} 

[@XAttribute]   // Refers to XAttribute 
class Class4 {} 

属性[X]是模糊的,因为它可以指代XXAttribute。使用逐字标识符可以在极少数情况下确定具体的意图。属性[XAttribute]不是不明确的(尽管如果有一个名为XAttributeAttribute的属性类!)。如果X类的声明被删除,那么这两个属性指向名为XAttribute属性类,如下所示:

using System; 
[AttributeUsage(AttributeTargets.All)] 
public class XAttribute: Attribute 
{} 

[X]     // Refers to XAttribute 
class Class1 {} 

[XAttribute]   // Refers to XAttribute 
class Class2 {} 

[@X]     // Error: no attribute named "X" 
class Class3 {} 
7

这是同样的事情。 [XAttribute] == [X]

MSDN

按照惯例,所有的属性名结束 打出 “属性” 以 在 .NET Framework中与其他项目区别开来。但是,在使用代码中的属性时,您不需要指定 后缀的属性 。 例如,[DllImport]相当于 到[DllImportAttribute],但DllImportAttribute是属性的 .NET Framework中的实际名称。

我们还可以读到:

如果属性类的都 有没有这个后缀发现,一个 不确定性存在,并且 编译时错误的结果。如果 属性名字的拼写是使得 其最右边的标识符是 逐字标识符,则只有未经 后缀的属性相匹配,从而使这种 歧义有待解决:

using System; 

[AttributeUsage(AttributeTargets.All)] 
public class X: Attribute 
{} 
[AttributeUsage(AttributeTargets.All)] 
public class XAttribute: Attribute 
{} 
[X]     // Error: ambiguity 
class Class1 {} 
[XAttribute]   // Refers to XAttribute 
class Class2 {} 
[@X]     // Refers to X 
class Class3 {} 
[@XAttribute]   // Refers to XAttribute 
class Class4 {} 
3

它在C#-compiler的约定。像它说的MSDN-page on 'Using Attributes'

按照惯例,所有的属性名结束 的“属性”字 从 .NET Framework中的其他项目区别开来。但是,在使用代码中的属性时,您不需要指定 后缀的属性 。 例如,[的DllImport]等价 到[DllImportAttribute],但 DllImportAttribute是属性的 在.NET Framework实际名称。

它的工作原理the same way in VB.NET

+0

你说这是.NET Framework中的惯例,那么为什么你应该区分C#和VB.NET? – serhio 2010-01-27 11:10:43