为什么我可以使用简写的`[Authorize]`而不是实际类的名称,`[AuthorizeAttribute]`?

时间:2014-03-07 16:36:48

标签: c# asp.net-mvc

我正在浏览ASP.NET Web堆栈源代码,并注意到AuthorizateAttribute类实际上是这样命名的(see here)。

那么,为什么我可以使用[Authorize]来应用属性......但这并不是Class的名称。该类的名称为AuthorizateAttribute

我实际上已将代码复制/粘贴到我自己的解决方案中,并将该类重命名为JeffthorizeAttribute,并且我不能将[Jeffthorize]属性添加到我的MVC控制器中。

为什么它接受缩短的版本而不是完整的类名?父属性类中是否存在自动计算出来的东西?

试图理解:(

4 个答案:

答案 0 :(得分:9)

当您使用属性(语法明显)时,C#编译器会自动尝试附加后缀Attribute。它只会让事情变得更容易。从C# 5 spec部分17.2(属性规范):

  

按照惯例,属性类的后缀为Attribute type-name 形式的属性名称可以包含或省略此后缀。如果找到带有和不带此后缀的属性类,则会出现歧义,并且会产生编译时错误。如果属性名称拼写为其最右侧标识符是逐字标识符(§2.4.2),则只匹配没有后缀的属性,从而可以解决这种歧义

能够使用你的[Jeffthroize]示例 - 如果没有看到代码和错误消息,很难说明为什么你不能在特定情况下使用。

例如,这很好:

using System;

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

[FooAttribute] // Full name
class Test 
{
    [Foo] // Abbreviated name
    public static void Main() {}
}

如果您尝试使用[@Foo],那将无效 - 但[@FooAttribute]有效。

另请注意VB has the same shorthand

答案 1 :(得分:4)

它基本上是由编译器强制执行的语法糖。按照惯例,您可以引用不带后缀的属性。

http://msdn.microsoft.com/en-us/library/84c42s56(v=vs.110).aspx

  

按照惯例,属性类的名称以单词结尾   属性。虽然不是必需的,但建议使用此约定   可读性。应用该属性时,包含该单词   属性是可选的。

答案 2 :(得分:1)

因为这是要在一个或多个类上使用的属性的命名标准。

答案 3 :(得分:0)

嗯,简单地说,它被接受,因为编译器是以这种方式编写的。

要求所有Attribute s 必须派生自Attribute类。因此,可以假设括号[]中的所有内容都是“属性”。

有一个程序员的习惯,XXXX经常被命名为XxxxThing,PersonView,LoginController,ReadOnlyAttribute。当您查看文件时,它可以让您更好地查看代码。但是,当你只处理控制器,只处理视图或只处理属性时,必须总是说XxxxAttribute,YyyyAttribute。

由于知道[]中写的所有内容都属于Attribute类,因此不必编写类中包含的Attribute字名称。它没有任何补充。你知道这是一个属性,因为它在[]

它只是语言/编译器提供的一个方便的快捷方式,仅为方便起见,并且仅在代码中的这个位置可用。如果您使用Reflection搜索该属性类,或者尝试Activator.Create<>甚至typeof(),则仍需要全名。

关于自定义属性的问题:

  • 确保您的using正确
  • 确保您已添加参考
  • 确保您已重新编译所有程序集
  • 确保typeof(JeffthrotizeAttribute)不会抱怨未知类型。如果是这样 - 进入前三点
  • 如果编译器仍然抱怨[Jeffthrotize],那么你可能会错误地标记错误。请注意,需要属性才能正确指定AttributeUsage。如果指定AttributeTargets.Method,那么您将无法将该属性放在整个类上。您可以将属性使用与|运算符结合使用,例如任何标记:AttributeTargets.Method|AttributeTargets.Class等。

有关完整列表,请参阅http://msdn.microsoft.com/pl-pl/library/system.attributetargets.aspx