C # Features and Index (C # Learning Notes 06)

Characteristic

Attribute is a declarative tag used to transfer behavior information of various elements in a program (such as classes, methods, structures, enumerations, components, etc.) at runtime.
Features can be viewed as a special class

Enumeration Characteristic Grammar:

 [attribute(positional_parameters, name_parameter = value, ...)] 
 element

Attribute is the attribute name, positional_parameters, name_parameter is the attribute attribute, value is the value of name_parameter attribute.

Three predefined characteristics:

The. Net Framework provides three predefined features:

1. AttributeUsage

This feature describes how user-defined feature classes are used
AttributeUsage basic structure:

 [AttributeUsage( validon, 
 AllowMultiple=allowmultiple, 
 Inherited=inherited )]

Example:

 [AttributeUsage(AttributeTargets.Class | 
 AttributeTargets.Constructor | 
 AttributeTargets.Field | 
 AttributeTargets.Method | 
 AttributeTargets.Property, 
 AllowMultiple = true)]

 

validon specifies that the feature can be hosted, or can be used by those types of declarations, such as the example shows that the feature can only be used in Class (class), constructor (structure), Field (field), Method (method), Property (property).
AllowMutiple specifies whether it can be reused, and if true, it can be reused.
Inherited specifies whether this feature can be inherited by derived classes, default false is non-inheritable and true is inheritable.

2.Conditional

This predefined feature marks a conditional method whose execution depends on a specific preprocessing identifier
It causes conditional compilation of method calls, depending on the specified values, such as Debug or Trace. For example, display the value of a variable when debugging code
The basic structure of Conditional:

 [
Conditional( 
 conditionalSymbol 
 )]

Use examples:

#define hong
using System;
using System.Diagnostics;
public class Myclass
{
    [Conditional("hong")]                            //Predefined Conditional Characteristic
    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();
    }
}

 

The program predefines a macro: hong. The Conditional feature is used in the function Message: [Conditional("hong")] If there is no macro definition, the function Message will not be executed.

1. If a macro is defined, the program runs as follows: (Message is called)

In Main function.
In Function 1.
In Function 2.
C: C code Conditional bin Debug netcoreapp3.0 Conditional. exe (process 18092) has exited and the return code is: 0.
To automatically close the console when debugging stops, enable Tools - > Options - > Debugging - > Automatically close the console when debugging stops.
Press any key to close this window.

2. If the first line is defined as macro annotations:

//#define hong
using System;
using System.Diagnostics;

 

Run (Message function will not be called at this time, there is no output):

C: C code Conditional bin Debug netcoreapp3.0 Conditional. exe (process 18264) has exited and the return code is: 0.
To automatically close the console when debugging stops, enable Tools - > Options - > Debugging - > Automatically close the console when debugging stops.
Press any key to close this window.
3.Obsolete

This predefined feature marks program entities that should not be used. It lets you notify the compiler to discard a particular 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 should use the new method instead of the old one.
Obsolete feature structure:

 [Obsolete(          
 message )] 
 
 [Obsolete(       
 message, 
 iserror )]

message: For descriptive purposes, the reason for not using this function and the replacement function
iserror: For bool values, true will cause compiler warnings by mistaking items that refer to this feature

Example:

    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();
    }
}

 

Running the compiler will prompt errors:

 Don't use OldMethod, use NewMethod instead

Steps to create custom features:

  • Declare custom features
  • Building custom features
  • Applying custom features on target program elements
  • Access feature by reflection

Detailed examples are done together after learning reflection.

reflex

A reflection object is used to get type information at run time. This class is located in the System.Reflection namespace and has access to the metadata of a running program.
The System.Reflection namespace contains classes that allow you to obtain information about the application and dynamically add types, values, and objects to the application.

Reflection has the following uses:

  1. It allows you to view attribute information at run time.
  2. It allows you to review the various types in a collection and instantiate them.
  3. It allows delayed binding of methods and properties.
  4. It allows new types to be created at runtime and then used to perform some tasks.

View metadata

using System;
[AttributeUsage(AttributeTargets.All)]                //Characterized to carry all types
public class HelpAttribute : System.Attribute         //Customization features HelpAttribute Inherit from Attribute Base class
{
    public readonly string Url;
    public string Topic   // Topic Is a parameter that represents a name
    {
        get
        {
            return topic;
        }
        set
        {
            topic = value;
        }
    }
    public HelpAttribute(string url)   // url Is a parameter that represents a position
    {
        this.Url = url;
    }
    private string topic;
}
public class OtherAttribute : System.Attribute
{
    public string topic2
    {
        get
        {
            return topic2;
        }
        set
        {
            topic2 = value;
        }
    }
}
[HelpAttribute("Information on the class MyClass")]          //Characteristics are applied MyClass In an empty class
[OtherAttribute()]                                           //Second feature
class MyClass
{

}

namespace AttributeAppl
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Reflection.MemberInfo info = typeof(MyClass);          //System.Reflection.MemberInfo Initialization
            object[] attributes = info.GetCustomAttributes(true);          //Getting the target class(MyClass)Characteristic Bearing
            for (int i = 0; i < attributes.Length; i++)                    //Traversing through all features
            {
                System.Console.WriteLine(attributes[i]);
            }
        }
    }
}

 

System.Reflection.MemberInfo info = typeof(MyClass);          
System.Reflection.MemberInfo needs to be initialized to associate with the target class (MyClass)

Result: (Returns two features hosted by MyClass class)

HelpAttribute
OtherAttribute

C: C code Feflection bin Debug netcoreapp3.0 Feflection. exe (process 6244) has exited and the return code is: 0.
To automatically close the console when debugging stops, enable Tools - > Options - > Debugging - > Automatically close the console when debugging stops.
Press any key to close this window...

Use features to set declaration information and access it with reflection

using System;
using System.Reflection;
namespace attribute
{
    [AttributeUsage(AttributeTargets.Class|            //Declare custom features and describe custom features DebugInfo How to be used
        AttributeTargets.Constructor|
        AttributeTargets.Field|
        AttributeTargets.Method|
        AttributeTargets.Property,
        AllowMultiple =true)]
    public class DebugInfo : Attribute                 //Building custom features
    {
        private int bugNo;          //bug number
        private string developer;
        private string lastReview;  //last reviewed
        public string message;
        public DebugInfo(int BN,string D,string LR)   //Constructor
        {
            this.bugNo = BN;
            this.developer = D;
            this.lastReview = LR;
        }
        public int BugNo
        {
            get
            {
                return bugNo;
            }
        }
        public string Developer
        {
            get
            {
                return developer;
            }
        }
        public string LastReview
        {
            get
            {
                return lastReview;
            }
        }
        public string Message
        {
            set
            {
                message = value;
            }
            get
            {
                return message;
            }
        }
    }
    [DebugInfo(45,"asahi","19/5/1",Message ="can't return type")]          //Applying custom features on target program elements
    [DebugInfo(50,"Lock","19/9/9",Message ="unable variable")]
    class Rectangle               //Rectangular class, which bears two properties
    {
        protected double length;
        protected double width;
        public Rectangle(double L,double W)
        {
            this.length = L;
            this.width = W;
        }
        [DebugInfo(55,"sayo","19/9/15",Message ="return false")]
        public double getArea()
        {
            return length * width;
        }
        [DebugInfo(60,"katsumi","19/10/1",Message ="output error")]
        public void Display()
        {
            Console.WriteLine("Length={0}", length);
            Console.WriteLine("Width={0}", width);
            Console.WriteLine("Area={0}", getArea());
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Rectangle r = new Rectangle(10, 5);
            r.Display();                                      

            Type type = typeof(Rectangle);                    //Obtain Rectangle Types
            //ergodic Rectangle Characteristic
            Console.WriteLine("                   Rectangle Type of Characteristic Testing:");
            foreach(object attributes in type.GetCustomAttributes(false))    //Obtain Rectangle All the features of the type, given by the way of iteration attributes
            {
                DebugInfo debugInfo = (DebugInfo)attributes;  //All features are converted to DebugInfo type
                if (debugInfo != null)
                {
                    Console.WriteLine("Debug number:{0}", debugInfo.BugNo);
                    Console.WriteLine("Developer:{0}", debugInfo.Developer);
                    Console.WriteLine("Last Review:{0}", debugInfo.LastReview);
                    Console.WriteLine("Message:{0}\n", debugInfo.Message);
                }
            }

            Console.WriteLine("           Rectangle Characteristic testing of all functions of type:");
            //Traversal method attributes
            foreach(MethodInfo m in type.GetMethods())      //ergodic type Type is Rectangle Type All Functions
            {
                foreach(object attributes in m.GetCustomAttributes(false))  //Characteristic of traversing every function
                {
                    DebugInfo debugInfo = (DebugInfo)attributes;
                    if (debugInfo != null)
                    {
                        Console.WriteLine("Debug number:{0}", debugInfo.BugNo);
                        Console.WriteLine("Developer:{0}", debugInfo.Developer);
                        Console.WriteLine("Last Review:{0}", debugInfo.LastReview);
                        Console.WriteLine("Message:{0}\n", debugInfo.Message);
                    }
                }
            }
        }
    }
}

Result:

Length=10
Width=5
Area=50
                   Rectangle Type of Characteristic Testing:
Debug number:45
Developer:asahi
Last Review:19/5/1
Message:can't return type

Debug number:50
Developer:Lock
Last Review:19/9/9
Message:unable variable

           Rectangle Characteristic testing of all functions of type:
Debug number:55
Developer:sayo
Last Review:19/9/15
Message:return false

Debug number:60
Developer:katsumi
Last Review:19/10/1
Message:output error


C:\Program Files\dotnet\dotnet.exe (process 8772)Exit, return code is: 0. 
//To automatically close the console when debugging stops, enable Tools->"Option "->"Debug "->"Automatically close the console when debugging stops.
//Press any key to close this window.

Reference link:

https://www.w3cschool.cn/wkcsharp/8jib1nvi.html

https://www.w3cschool.cn/wkcsharp/9phg1nvl.html

Tags: C# Attribute

Posted on Sat, 12 Oct 2019 13:30:03 -0700 by gmdavis