需要理解解决歧义的属性前的@符号

本文关键字:属性 符号 歧义 解决 | 更新日期: 2023-09-27 17:53:59

我正在向我的类的属性添加验证属性。我有一个库,假设是第三方库,它包含一个StringLengthAttribute。我们知道在System.ComponentModel.DataAnnotations下有一个同名的属性。
我在创建的类中同时使用第三方和System.ComponentModel.DataAnnotations。这就造成了对StringLengthAttribute的歧义。编译器建议在属性中使用@,如[@StringLength()]。我就是这么做的,但是当我尝试F12 (Go to definition)时,它把我带到了第三方库。

我想了解属性中的@符号是如何真正工作的,我想使用System.ComponentModel.DataAnnotation.StringLengthAttribute而不是第三方,我该如何做到这一点,因为第三方和DataAnnotation的两个名称空间都是在类的顶部使用部分声明的。

[@StringLength(10)]
public string Name { get; set; }

需要理解解决歧义的属性前的@符号

c#提供了一些语法糖,允许您在用属性修饰成员时省略单词Attribute。例如,如果您有一个名为MyCustomAttribute的属性,您可以在将其应用于方法时使用这种简写:

[MyCustom]
public void MyMethod()
{
  ...
}

这很好,直到你也声明了一个名为"MyCustom"的类,它也派生自Attribute。在这种情况下,c#编译器将不知道[MyCustom]是指MyCustom类还是MyCustomAttribute类。通过前缀你的属性使用@,你告诉编译器,你的意思是使用类与紧跟@的名称(即编译器不应该追加"属性")。所以[@MyCustom]指的是MyCustom类,而[@MyCustomAttribute]指的是MyCustomAttribute类。

在您使用[@StringLength(10)]的示例中,编译器将把该属性解析为名为StringLength的类,而不是名为StringLengthAttribute的类。

下面是c#语言规范中的一个例子,它可能比我解释得更好:

[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 {}