【问题标题】:Why can I use the shorthand `[Authorize]` instead of the name of the actual class, `[AuthorizeAttribute]`? [duplicate]为什么我可以使用简写“[Authorize]”而不是实际类的名称“[AuthorizeAttribute]”? [复制]
【发布时间】:2023-03-27 19:40:02
【问题描述】:

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

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

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

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

只是想明白:(

【问题讨论】:

  • 没什么不好的!很高兴你找到了。现在我们可以将这些问题联系在一起。

标签: c# asp.net-mvc


【解决方案1】:

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

按照惯例,属性类以Attribute 后缀命名。 type-name 形式的 attribute-name 可以包含或省略此后缀。如果找到带有和不带有此后缀的属性类,则会出现歧义,并导致编译时错误。如果 attribute-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

【讨论】:

  • 感谢您的意见。非常感谢。
  • @JGinSD:那是 C# 1.2 规范 - 不幸的是,我不认为有一个完整的 HTML 格式的 C# 5 规范。不过,我会在答案中添加指向 Word 版本的链接。
【解决方案2】:

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

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

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

【讨论】:

  • 我从来没有想过它会是一个编译器,或者只是一个特定于语言的“功能”。感谢您的快速回答。
  • C# 有几个基于约定的特性,例如默认情况下成员为private。 Jon Skeet 可能会给你比我更多的细节:)
【解决方案3】:

因为这是用于类或方法的属性的命名标准。

【讨论】:

    【解决方案4】:

    嗯,简单地说,它被接受了,因为编译器是这样写的。

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

    有一个程序员的习惯,东西 XXXX 通常被命名为 XxxxThing、PersonView、LoginController、ReadOnlyAttribute。当您查看文件时,它可以让您更好地了解代码。然而,当你只处理控制器、视图或属性时,总是不得不说 XxxxAttribute、YyyyAttribute 是很烦人的。

    由于您知道所有用[] 编写的东西都属于Attribute 类,因此没有必要在类名中写入Attribute 字。它什么也没增加。你知道它是一个属性,因为它在 [] 中。

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

    关于自定义属性的问题:

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

    查看http://msdn.microsoft.com/pl-pl/library/system.attributetargets.aspx查看完整列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 2017-09-27
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多