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

相关推荐

  • 2.6C#函数成员之索引器(Indexer)

    1.索引器声明 索引器的声明方式与属性相似,格式为索引器名称 this 后跟 分隔符 [ 和 ] 以及单个或多个参数。 2.访问器 类似于属性,索引器分为读写、只读和只写索引器。 3.接口中的索引器 接口访问器不使用修饰符。 接口访问器通常没有实现,仅指示索引…

    C#语言教程 2021年2月6日
    03200
  • 3.3C#值类型之枚举(Enum)

    枚举声明 所有枚举继承自 System.Enum类(继承自 System.ValueType)。 枚举类型 定义了一组常量值。 每个 enum 类型都有一个基础类型(必须是八种整型类型之一)。默认情况下,枚举常量的基础类型为 int,它们从 0 开始,并按定义…

    C#语言教程 2021年3月3日
    05210
  • 3.2C#值类型之结构(Struct)

    1.结构声明 struct 类型定义包含数据成员和函数成员的结构,这一点与类类型相似。 2.继承 所有结构类型只能隐式派生自 System.ValueType类,结构类型不能从其它类或结构类型继承,也不能作为类的基础类型,因为结构类型是隐式密封的。 3.构造函数 如果显式声明一个无参数构造函数,那创建对象调用无参数构造…

    C#语言教程 2021年3月2日
    05450

发表回复

登录后才能评论