C# Attribute
Attribute is used to pass various elements in the program at runtime ( Declarative tags for behavioral information such as classes, methods, structures, enumerations, components, etc.). You can add declarative information to your program by using attributes. A declarative tag is described by square brackets ([ ]) placed in front of the element to which it applies.
Attributes are used to add metadata, such as compiler instructions and comments, descriptions, methods, classes and other information. The .Net framework provides two types of attributes: Predefined attributes and Custom attributes.
Specify attributes (Attribute)
The syntax of specifying attributes (Attribute) is as follows:
[attribute(positional_parameters, name_parameter = value, ...)] element
The name and value of the attribute (Attribute) are specified in square brackets and placed where it before the applied element. positional_parameters specifies required information, name_parameter specifies optional information.
Predefined attributes (Attribute)
.Net framework provides three predefined attributes:
AttributeUsage
Conditional
Obsolete
AttributeUsage
Predefined attributesAttributeUsage describes how Use a custom attribute class. It specifies the types of items to which the feature can be applied.
The syntax for specifying this attribute is as follows:
[AttributeUsage( validon, AllowMultiple=allowmultiple, Inherited=inherited )]
Where:
Parameter validon specifies the language element in which the attribute can be placed. It is a combination of the values of the enumerator AttributeTargets. The default value is AttributeTargets.All.
Parameters allowmultiple (optional) Provide a boolean value for the AllowMultiple property of this feature. If true, the attribute is multipurpose. The default value is false (single use).
Parameters inherited (optional) Provides a boolean value for the Inherited property of this feature. If true, this attribute can be inherited by derived classes. The default value is false (not inherited).
For example:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
Conditional
This predefined attribute marks a conditional method whose execution depends on its top preprocessing identifier.
It causes conditional compilation of method calls, depending on the specified value, such as Debug or Trace. For example, display the value of a variable when debugging code.
The syntax for specifying this feature is as follows:
[Conditional( conditionalSymbol )]
For example:
[Conditional("DEBUG")]
The following example demonstrates this feature:
#define DEBUG using System; using System.Diagnostics; public class Myclass { [Conditional("DEBUG")] public static void Message(string msg) { Console.WriteLine(msg); } } class Test { static void function1() { Myclass.Message("In Function 1."); function2(); } static void function2() { Myclass.Message("In Function 2."); } public static void Main() { Myclass.Message("In Main function."); function1(); Console.ReadKey(); } }
When the above code is compiled and when executed, it produces the following results:
In Main function In Function 1 In Function 2
Obsolete
This predefined attribute marks program entities that should not be used. It lets you tell the compiler to discard a specific target element. For example, when a new method is used in a class, but you still want to keep the old method in the class, you can mark it as obsolete by displaying a message that the new method should be used instead of the old method. of).
The syntax for this feature is as follows:
[Obsolete( message )] [Obsolete( message, iserror )]
Among them:
Parameter message is a string describing the project Reason why it is obsolete and what to use instead.
Parameter iserror is a Boolean value. If this value is true, the compiler should treat the use of this item as an error. The default value is false (the compiler generates a warning).
The following example demonstrates this feature:
using System; public class MyClass { [Obsolete("Don't use OldMethod, use NewMethod instead", true)] static void OldMethod() { Console.WriteLine("It is the old method"); } static void NewMethod() { Console.WriteLine("It is the new method"); } public static void Main() { OldMethod(); } }
When you try to compile this program, the compiler will give an error message stating:
Don't use OldMethod, use NewMethod instead
Create custom attributes (Attribute)
.Net framework allows the creation of custom attributes that are used to store declarative information and can be retrieved at runtime. This information can be associated with any target element based on design criteria and application needs.
Creating and using custom properties involves four steps:
Declare custom properties
Build custom properties
Apply custom attributes on the target program element
Access attributes via reflection
Last one The steps include writing a simple program to read the metadata in order to find various symbols. Metadata is data and information used to describe other data. The program should use reflection to access properties at runtime. We will discuss this in detail in the next chapter.
Declaring custom attributes
A new custom attribute should be derived from the System.Attribute class. For example:
// 一个自定义特性 BugFix 被赋给类及其成员 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute
In the above code, we have declared a custom attribute named DeBugInfo.
Building a Custom Attribute
Let's build a custom attribute called DeBugInfo that will store the information obtained by the debugger. It stores the following information:
The code number of the bug
The name of the developer who identified the bug
-
The date this code was last reviewed
A string message that stores developer flags
Our DeBugInfo The class will have three private properties (property) used to store the first three information and one public property (property) used to store the message. So the bug number, developer name, and review date will be required positional parameters of the DeBugInfo class, and the message will be an optional named parameter.
Each attribute must have at least one constructor. Required positional parameters should be passed through the constructor. The following code demonstrates the DeBugInfo class:
// 一个自定义特性 BugFix 被赋给类及其成员 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute { private int bugNo; private string developer; private string lastReview; public string message; public DeBugInfo(int bg, string dev, string d) { this.bugNo = bg; this.developer = dev; this.lastReview = d; } public int BugNo { get { return bugNo; } } public string Developer { get { return developer; } } public string LastReview { get { return lastReview; } } public string Message { get { return message; } set { message = value; } } }
Applying a custom attribute
Apply the attribute by placing it immediately before its target:
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")] [DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")] class Rectangle { // 成员变量 protected double length; protected double width; public Rectangle(double l, double w) { length = l; width = w; } [DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")] public double GetArea() { return length * width; } [DeBugInfo(56, "Zara Ali", "19/10/2012")] public void Display() { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea()); } }
In the next chapter, we will use the Reflection class object to retrieve this information.