3.9C#引用类型之特性(Attribute)

1.特性声明

所有特性类都直接或间接派生自 System.Attribute 基类。

以下示例声明了 HelpAttribute 特性。

using System;

public class HelpAttribute : Attribute
{
    string _url;
    string _topic;

    public HelpAttribute(string url) => _url = url;

    public string Url => _url;

    public string Topic
    {
        get => _topic;
        set => _topic = value;
    }
}

2.调用特性

调用特性时,通过用方括号 ([]) 将特性名称以及实参括起来,并置于应用该特性的实体的声明上方。可以将多个特性附加到实体的声明上。对于给定实体,一些特性可以指定多次。

按位置传递的参数与特性构造函数的参数相对应,按命名传递的参数与该特性的属性或字段相对应。

如果特性的名称以 Attribute 结尾,那么可以在调用特性时省略 Attribute

[Help("http://msdn.microsoft.com/.../MyClass.htm")]
public class Widget
{
    [Help("http://msdn.microsoft.com/.../MyClass.htm", Topic = "Display")]
    public void Display(string text) {}
}

3.特性目标

默认情况下,特性应用于紧跟在它后面的元素。特性目标是显式的指定此特性应用于哪个目标。

[target : attribute-list]

NonSerializedAttribute 只能附加到字段,不能附加到属性。可使用特性上的 field: 说明符将 NonSerializedAttribute 附加到 Id 属性的支持字段,如下例所示:

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    [field:NonSerialized]
    public int Id { get; set; }

    public string FullName => $"{FirstName} {LastName}";
}
target值应用场景
assembly整个程序集
module当前程序集模块
field类或结构中的字段
event事件
method方法或 get 和 set 属性访问器
param方法参数或 set 属性访问器参数
property属性
return方法、属性索引器或 get 属性访问器的返回值
type结构、类、接口、枚举或委托

4.特性命名

特性的命名按照PascalCase + Attribute方式,虽然编译器不强制带Attribute结尾,但这是良好的编码习惯。

但是,如果两个短名称相同,并且一个类型名称包含 Attribute 后缀而另一类型名称不包含,则会出现命名冲突。可以使用 @ 字符指定是调用全名。

using System;

[AttributeUsage(AttributeTargets.Class)]
public class Info : Attribute
{
   private string information;

   public Info(string info)
   {
      information = info;
   }
}

[AttributeUsage(AttributeTargets.Method)]
public class InfoAttribute : Attribute
{
   private string information;

   public InfoAttribute(string info)
   {
      information = info;
   }
}


// Generates compiler error CS1614. Ambiguous Info and InfoAttribute.
[Info("A simple executable.")] 
// Prepend '@' to select 'Info' ([@Info("A simple executable.")]). Specify the full name 'InfoAttribute' to select it.
public class Example
{
   [InfoAttribute("The entry point.")]
   public static void Main()
   {
   }
}

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/csharp/csharplang/11487.html

(0)
上一篇 2021年3月8日 05:37
下一篇 2021年3月10日 20:35

相关推荐

  • 3.1C#语言的命名空间(Namespace)

    1.命名空间声明 C# 10 中可使用文件范围的命名空间声明,一个文件中的所有类型都在一个命名空间中。文件范围的命名空间不能声明嵌套的命名空间或第二个文件范围的命名空间。 可以在两个或多个声明中定义一个命名空间。 2.using指令 2.1导入其它命名空间的类型 2.2创建命名空间别名 using 指令的声明…

    C#语言教程 2021年3月1日
    07340
  • 3.13C#语言的泛型(Generic)

    1.泛型类 类型参数跟在类名后面。 2.泛型接口 类型参数跟在接口名后面。 3.泛型方法 类型参数跟在方法名后面。 方法调用时,可以根据实参推断出类型参数的类型,无需显式指定。 4.构造(Constructed)类型 封闭式构造(closed constructed)类型:指定类型参数,例如,Node<int&g…

    C#语言教程 2021年3月13日
    02390
  • 1.3C#语言的运算符(Operator)和表达式(Expression)

    1.一元运算符 运算符 描述 +x 一元 + 运算符返回其操作数的值。 -x 一元 – 运算符对其操作数的数值取负。 ++x ++x 的结果是按 1 递增其操作数后的 x 的值。 –x –x 的结果是按 1 递减其操作数后的 …

    C#语言教程 2021年1月3日
    08220

发表回复

登录后才能评论