C# learning notes - Reflection and characteristics

Keywords: C#

1. Reflection

The program is used to process data. Text and characteristics are data. The program itself (class definition and class in BLC) is also data. The data about the program and its type is called metadata and stored in the assembly of the program.

The behavior of a running program to view its own metadata or the metadata of other assemblies is called reflection.

1.1 Type

Predefined types (int, long, string, etc.), types in BCL (Console,IEnumerable, etc.) and programmer defined types (MyClass,MyDel, etc.). Each type has its own members and properties. The type abstract class is used to contain the properties of the type. Objects using this class can get information about the types used by the program. Type is an abstract class and cannot instantiate an object.

1.2 get Type object

Create a class that declares fields, properties, and methods

class MyClass
    {
        private int id;
        private int age;
        public int number;
        public string Name { get; set; }
    	public string Name2 { get; set; }
        public string Name3 { get; set; }
        public void Test1() { }
        public void Test2() { }
    }
static void Main(string[] args)
        {
           Each class corresponds to one type Object, this type Object stores the methods, data and members of this class
            MyClass my = new MyClass();//The data in a class is stored in the object, but the type object only stores the members of the class
            Type type = my.GetType();//Get the Type object of the class to which this object belongs through the object
            Console.WriteLine(type.Name);//Gets the name of the class
            Console.WriteLine(type.Namespace);//Gets the namespace where the
            Console.WriteLine(type.Assembly);//Class assembly
            FieldInfo[] array = type.GetFields();//Get the fields of the class. Only public fields can be obtained
            foreach (FieldInfo info in array)
            {
                Console.Write(info.Name + " ");
            }
            PropertyInfo[] array2 = type.GetProperties();//Get property name
            foreach (PropertyInfo info in array2)
            {
                Console.Write(info.Name + " ");
            }
            MethodInfo[] array3 = type.GetMethods();//Get method name
            foreach (MethodInfo info in array3)
            {
                Console.Write(info.Name + " ");
            }
    
            Console.ReadKey();

        }

Operation results:

1.3 get assembly

class Program
    {
        static void Main(string[] args)
        {
            MyClass my = new MyClass();
            Assembly assem = my.GetType().Assembly;//Get the Assembly assembly of the class through its type object
            Console.WriteLine(assem.FullName);//Gets the full name of the assembly
            Type[] types = assem.GetTypes();//Gets all types in the assembly
            foreach (var type in types)
            {
                Console.WriteLine(type);
            }

            Console.ReadKey();

        }
}

Operation results:

2. Characteristics

An attribute is a language structure that allows us to add metadata to an assembly of an assembly. It is a special type of class used to store program structure information.

The program structure to which features are applied is called a goal. For example, the following methods or parameters applied to features are called goals.

Programs designed to obtain and use metadata (object browsers) are called feature consumers. For example, the method that the VS compiler reads the Obsolete feature is discarded, and the compiler is the consumer of this feature.

2.1 Obsolete characteristics

class Program
    {
        [Obsolete("This method is deprecated. Please use the latest one NewTest method")]//Properties: deprecated
        static void Test()
        {
            Console.WriteLine("Test");
        }

        static void NewTest()
        {
            Console.WriteLine("NewTest");
        }

        static void Main(string[] args)
        {
            Test();
        }   
    }

When the mouse hovers over the discarded method, the corresponding prompt will be given

2.2 Conditional features:

#define IsShowMessage 
//Define a macro. Only when it is defined can the method of IsShowMessage attribute be called

class Program
    {
        [Conditional("IsShowMessage")]
        static void ShowMessage(string str)
        {
            Console.WriteLine(str);
        }

        static void Main(string[] args)
        {
            ShowMessage("Start of Main");
            Console.WriteLine("Doing work");
            ShowMessage("End of Main");
        }   
    }

Operation results:

When no macro is defined, the method of the IsShowMessage attribute is not called

2.3 caller information characteristics

class Program
{
    static void ShowMessage(string message,[CallerLineNumber]int lineNumber = 0,[CallerFilePath]string filePath="",[CallerMemberName]string memberName="")
    {
        Console.WriteLine(message);
        Console.WriteLine(lineNumber);//Number of lines of code calling this method
        Console.WriteLine(filePath);//The file path where this method is called
        Console.WriteLine(memberName);//The name of the method that called this method
    }

    static void Main(string[] args)
    {
        ShowMessage("Hello");
    }   
}

Operation results:

2.4 DebuggerStepThrough feature

When the power-off is set for debugging, the structure of this feature will not be interrupted. It will be interrupted after running the structure directly, for example:

class Program
{
    [DebuggerStepThrough]
    static void ShowMessage(string message,[CallerLineNumber]int lineNumber = 0,[CallerFilePath]string filePath="",[CallerMemberName]string memberName="")
    {
        Console.WriteLine(message);
        Console.WriteLine(lineNumber);//Number of lines of code calling this method
        Console.WriteLine(filePath);//The file path where this method is called
        Console.WriteLine(memberName);//The name of the method that called this method
    }

    static void Main(string[] args)
    {
        ShowMessage("Hello");
        Console.WriteLine("helloworld")
    }   
}

Adding breakpoints to the two fields of the Main method will not jump into the ShowMessage method. The next step will be directly interrupted in the second line

2.5 custom properties

//The attribute class should represent some state of the target structure
//If the attribute requires some fields, data can be collected by including a constructor with positional parameters, and optional fields can be initialized on demand with named parameters
//Do not implement public methods and other function members other than properties
//The attribute class is declared sealed
//Use AttributeUsage in the attribute declaration to specify the attribute target group
[AttributeUsage(AttributeTargets.Class)]
    internal sealed class InformationAttribute:Attribute
    {
        public string developer;
        public string version;
        public string description;

        public InformationAttribute(string developer, string version, string description)
        {
            this.developer = developer;
            this.version = version;
            this.description = description;
        }
    }
//Access characteristics
[Information("Cheese","1.1","Rocket launching class")]
    internal class Program
    {
        static void Main(string[] args)
        {
            //Call the IsDefined method through the Type object
            Type t = typeof(Program);

            //IsDefined access feature to judge whether a feature is applied to the class
            bool result = t.IsDefined(typeof(InformationAttribute), false);
            Console.WriteLine(result);

            //To return an array of object s, we must cast it into the attribute type of the corresponding type
            //The bool parameter specifies whether it searches the inheritance tree for attributes
            //When this method is called, each instance of the feature associated with the target is created
            object[] attArray = t.GetCustomAttributes(false);
        }
    }

Posted by artyfarty on Sat, 04 Dec 2021 16:24:52 -0800