C#属性名称缩写

25

C#属性为什么在名称中包含“Attribute”(例如DataMemberAttribute),但在初始化时却没有这个后缀?例如:

[DataMember]
private int i;

我想强调的是,问题是“如何”实现还没有得到回答。但我相信它使用反射X OR X +“Attribute”来搜索名称。 - serhio
1
@serhio 根据 Anton Gogolev 的说法,这是编译器提供的快捷方式。如果这是正确的答案,那对我来说就足够了。而且它也适用于自定义属性。 - Fabiano
对我个人而言,编译器能提供什么样的“快捷方式”并不是很清楚。 - serhio
@serhio - 或许更少的名字需要携带?这似乎有点不一致(编译器是否会从类名后缀中删除“class”?),但至少是有道理的。 - StingyJack
3个回答

24
根据C#语言规范,按照惯例,属性类的名称应以Attribute为后缀。形如type-nameattribute-name可以包含或省略此后缀。
这是C#编译器提供的一种快捷方式,绝非CLR功能。另一个编译器对属性的特殊处理是ObsoleteAttribute属性:它会强制编译器发出警告/错误,但对于CLR没有特殊意义。
至于如何解析属性,请参见上面的链接。总之:
如果既找到带有该后缀的属性类,又找到不带该后缀的属性类,则存在歧义,结果会产生编译时错误。如果attribute-name的拼写使其最右边的标识符是verbatim identifier,则只匹配不带后缀的属性,从而使这种歧义得到解决。
“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]是有歧义的,因为它可以指代X或者XAttribute。在这种罕见情况下,使用逐字标识符可以指定确切意图。属性[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

按照惯例,所有属性名称都以单词“Attribute”结尾,以区别于.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#编译器的约定。正如在“使用属性”页面上所述:(英文链接)

按照惯例,所有属性名称都以单词“Attribute”结尾,以将它们与.NET Framework中的其他项区分开来。但是,在代码中使用属性时,您无需指定属性后缀。例如,[DllImport]等同于[DllImportAttribute],但DllImportAttribute是.NET Framework中该属性的实际名称。

在VB.NET中工作方式相同


你说这是.NET框架的惯例,那么为什么你要区分C#和VB.NET呢? - serhio

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