文档
-
了解如何检索存储在属性中的信息,包括属性实例、同一作用域的多个实例、适用于不同作用域的多个实例以及应用于类成员的属性。
-
了解特性在 C# 中的工作方式。 定义自定义特性以向代码添加元数据。 读取这些特性以在运行时了解代码
-
了解如何通过定义从特性类派生的特性类,在 C# 中创建自定义特性。
若要设计自定义属性,无需了解许多新概念。 如果你熟悉面向对象的编程并知道如何设计类,则你已拥有所需的大部分知识。 自定义属性是直接或间接派生自 System.Attribute 类的传统类。 与传统类一样,自定义属性包含存储和检索数据的方法。
正确设计自定义属性类的主要步骤如下:
本部分介绍上述每个步骤,最后以 自定义属性示例结束。
自定义属性声明以属性开头 System.AttributeUsageAttribute ,该特性定义属性类的一些关键特征。 例如,可以指定属性是否可以由其他类继承,或者属性可以应用于哪些元素。 以下代码片段演示如何使用 AttributeUsageAttribute:
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
<AttributeUsage(AttributeTargets.All, Inherited:=False, AllowMultiple:=True)>
Public Class SomeClass
Inherits Attribute
'...
End Class
这 AttributeUsageAttribute 三个成员对于创建自定义属性非常重要: AttributeTargets、 Inherited 和 AllowMultiple。
在前面的示例中, AttributeTargets.All 指定了此属性,指示此属性可应用于所有程序元素。 或者,可以指定 AttributeTargets.Class,指示属性只能应用于类,或者 AttributeTargets.Method指示属性只能应用于方法。 所有程序元素都可以以这种方式被自定义属性标记为说明。
还可以传递多个 AttributeTargets 值。 以下代码片段指定可将自定义属性应用于任何类或方法:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method)>
Public Class SomeOtherClass
Inherits Attribute
'...
End Class
该 AttributeUsageAttribute.Inherited 属性指示属性是否可以由派生自应用属性的类继承。 此属性采用 true
(默认值)或 false
标志。 在以下示例中,MyAttribute
默认值Inheritedtrue
为 ,而YourAttribute
Inherited默认值为false
:
// This defaults to Inherited = true.
public class MyAttribute : Attribute
{
//...
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class YourAttribute : Attribute
{
//...
}
' This defaults to Inherited = true.
Public Class MyAttribute
Inherits Attribute
'...
End Class
<AttributeUsage(AttributeTargets.Method, Inherited:=False)>
Public Class YourAttribute
Inherits Attribute
'...
End Class
然后,这两个属性将应用于基类 MyClass
中的方法:
public class MyClass
{
[MyAttribute]
[YourAttribute]
public virtual void MyMethod()
{
//...
}
}
Public Class MeClass
<MyAttribute>
<YourAttribute>
Public Overridable Sub MyMethod()
'...
End Sub
End Class
最后,类 YourClass
继承自基类 MyClass
。 该方法MyMethod
显示但不MyAttribute
显示YourAttribute
:
public class YourClass : MyClass
{
// MyMethod will have MyAttribute but not YourAttribute.
public override void MyMethod()
{
//...
}
}
Public Class YourClass
Inherits MeClass
' MyMethod will have MyAttribute but not YourAttribute.
Public Overrides Sub MyMethod()
'...
End Sub
End Class
该 AttributeUsageAttribute.AllowMultiple 属性指示属性的多个实例是否可以存在于元素上。 如果设置为 true
,则允许多个实例。 如果设置为 false
(默认值),则只允许一个实例。
在以下示例中,MyAttribute
默认值AllowMultiplefalse
为 ,而YourAttribute
默认值为true
:
//This defaults to AllowMultiple = false.
public class MyAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
' This defaults to AllowMultiple = false.
Public Class MyAttribute
Inherits Attribute
End Class
<AttributeUsage(AttributeTargets.Method, AllowMultiple:=true)>
Public Class YourAttribute
Inherits Attribute
End Class
应用这些属性的多个实例时, MyAttribute
生成编译器错误。 下面的代码示例显示了有效用法 YourAttribute
和无效用法 MyAttribute
:
public class MyClass
{
// This produces an error.
// Duplicates are not allowed.
[MyAttribute]
[MyAttribute]
public void MyMethod()
{
//...
}
// This is valid.
[YourAttribute]
[YourAttribute]
public void YourMethod()
{
//...
}
}
Public Class MyClass
' This produces an error.
' Duplicates are not allowed.
<MyAttribute>
<MyAttribute>
Public Sub MyMethod()
'...
End Sub
' This is valid.
<YourAttribute>
<YourAttribute>
Public Sub YourMethod()
'...
End Sub
End Class
AllowMultiple如果属性和Inherited属性都设置为true
,则从另一个类继承的类可以继承属性,并让同一子类中应用同一属性的另一个实例。 如果
应用后 AttributeUsageAttribute,开始定义属性的具体信息。 特性类的声明类似于传统类的声明,如以下代码所示:
[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
// . . .
}
<AttributeUsage(AttributeTargets.Method)>
Public Class MyAttribute
Inherits Attribute
' . . .
End Class
此属性定义演示了以下几点:
属性类必须声明为公共类。
按照约定,属性类的名称以“ 属性”一词结尾。 虽然不需要,但建议使用此约定进行可读性。 应用该属性时,包含“属性”一词是可选的。
所有属性类必须直接或间接地从 System.Attribute 类继承。
在 Microsoft Visual Basic 中,所有自定义属性类都必须具有该 System.AttributeUsageAttribute 属性。
与传统类一样,属性使用构造函数进行初始化。 以下代码片段演示了典型的属性构造函数。 此公共构造函数采用参数并设置一个等于其值的成员变量。
public MyAttribute(bool myvalue)
{
this.myvalue = myvalue;
}
Public Sub New(myvalue As Boolean)
Me.myvalue = myvalue
End Sub
可以重载构造函数以适应值的不同组合。 如果还为自定义属性类定义 属性 ,则可以在初始化属性时使用命名参数和位置参数的组合。 通常,将所有必需的参数定义为位置参数和命名的所有可选参数。 在这种情况下,如果没有必需的参数,则无法初始化特性。 所有其他参数都是可选的。
备注
在 Visual Basic 中,属性类的构造函数不应使用 ParamArray
参数。
下面的代码示例演示如何使用可选参数和必需参数应用使用上一个构造函数的属性。 它假定该属性具有一个必需的布尔值和一个可选的字符串属性。
// One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
public class SomeClass
{
//...
}
// One required (positional) parameter is applied.
[MyAttribute(false)]
public class SomeOtherClass
{
//...
}
' One required (positional) and one optional (named) parameter are applied.
<MyAttribute(false, OptionalParameter:="optional data")>
Public Class SomeClass
'...
End Class
' One required (positional) parameter is applied.
<MyAttribute(false)>
Public Class SomeOtherClass
'...
End Class
如果要定义命名参数或提供返回属性存储的值的简单方法,请声明 属性。 属性属性应声明为公共实体,其中包含将返回的数据类型的说明。 定义将保存属性值的变量,并将其与 get
和 set
方法相关联。 下面的代码示例演示如何在属性中实现属性:
public bool MyProperty
{
get {return this.myvalue;}
set {this.myvalue = value;}
}
Public Property MyProperty As Boolean
Get
Return Me.myvalue
End Get
Set
Me.myvalue = Value
End Set
End Property
本部分包含前面的信息,并演示如何设计一个属性,该属性记录有关代码节的作者的信息。 此示例中的属性存储程序员的名称和级别,以及代码是否已评审。 它使用三个私有变量来存储要保存的实际值。 每个变量由获取和设置值的公共属性表示。 最后,使用两个必需参数定义构造函数:
[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : Attribute
{
// Private fields.
private string name;
private string level;
private bool reviewed;
// This constructor defines two required parameters: name and level.
public DeveloperAttribute(string name, string level)
{
this.name = name;
this.level = level;
this.reviewed = false;
}
// Define Name property.
// This is a read-only attribute.
public virtual string Name
{
get {return name;}
}
// Define Level property.
// This is a read-only attribute.
public virtual string Level
{
get {return level;}
}
// Define Reviewed property.
// This is a read/write attribute.
public virtual bool Reviewed
{
get {return reviewed;}
set {reviewed = value;}
}
}
<AttributeUsage(AttributeTargets.All)>
Public Class DeveloperAttribute
Inherits Attribute
' Private fields.
Private myname As String
Private mylevel As String
Private myreviewed As Boolean
' This constructor defines two required parameters: name and level.
Public Sub New(name As String, level As String)
Me.myname = name
Me.mylevel = level
Me.myreviewed = False
End Sub
' Define Name property.
' This is a read-only attribute.
Public Overridable ReadOnly Property Name() As String
Get
Return myname
End Get
End Property
' Define Level property.
' This is a read-only attribute.
Public Overridable ReadOnly Property Level() As String
Get
Return mylevel
End Get
End Property
' Define Reviewed property.
' This is a read/write attribute.
Public Overridable Property Reviewed() As Boolean
Get
Return myreviewed
End Get
Set
myreviewed = value
End Set
End Property
End Class
可以通过以下方法之一使用全名 DeveloperAttribute
或缩写名称 Developer
来应用此属性:
[Developer("Joan Smith", "1")]
-or-
[Developer("Joan Smith", "1", Reviewed = true)]
<Developer("Joan Smith", "1")>
-or-
<Developer("Joan Smith", "1", Reviewed := true)>
第一个示例演示仅应用了必需的命名参数的属性。 第二个示例显示了使用必需参数和可选参数应用的属性。
文档
了解如何检索存储在属性中的信息,包括属性实例、同一作用域的多个实例、适用于不同作用域的多个实例以及应用于类成员的属性。
了解特性在 C# 中的工作方式。 定义自定义特性以向代码添加元数据。 读取这些特性以在运行时了解代码
了解如何通过定义从特性类派生的特性类,在 C# 中创建自定义特性。
培训
认证
Microsoft认证:Azure开发者助理 - Certifications
在 Microsoft Azure 中构建端到端解决方案,以创建 Azure Functions、实现和管理 Web 应用、开发使用 Azure 存储的解决方案等。