Reflection and properties in C #

Keywords: C# reflection

Reflection and characteristics in C # (II)

Previous section Reflection and characteristics in C # (I) , after a brief understanding of what reflection is and some of its features, let's continue to learn about other features in C#.

1.Assembly class

The Assembly class is defined in the System.Reflection namespace. It allows access to the metadata of a given Assembly. It also contains assemblies that can be loaded and executed.

For example, we add the following code on the basis of the content described in the previous chapter:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Test_Reflection_and_characteristic
{
    class Program
    {
        static void Main(string[] args)
        {
            //Myclass my = new Myclass();// Each class corresponds to a type object, which stores the class, which methods, which methods and which members
            //Type testType = my.GetType();// The data in a class is stored in the object, but the type object only stores the members of the class
            //Console.WriteLine("namespace referenced by output testType: {0}", testType);
            //Console.WriteLine("get the class name referenced by the current testType: {0}", testType.Name);
            //Console.WriteLine("output assembly in current testtype: {0}", testType.Assembly);
            //Console.WriteLine("output the attribute associated with the current testType: {0}", testType.Attributes);        
adopt FieldInfo To access fields
        //FieldInfo[] array = testType.GetFields();
        //foreach (FieldInfo info in array)
        //{
        //    //Note that only public fields can be accessed, and private fields cannot be accessed
        //    Console.WriteLine("output the field {0} contained in the current testType", info. Name);
        //}

        //PropertyInfo[] array2 = testType.GetProperties();
        //foreach (PropertyInfo info in array2)
        //{
        //    //Note that only public attributes can be accessed, and private attributes cannot be accessed
        //    Console.WriteLine("output the property {0} contained in the current testType", info. Name);
        //}

        //MethodInfo[] array3 = testType.GetMethods();
        //foreach (MethodInfo info in array3)
        //{
        //    //Note that only public methods can be accessed, while private methods cannot
        //    Console.WriteLine("output the method {0} contained in the current testType", info. Name);
        //}  
        Myclass my = new Myclass();
        Assembly myassem = my.GetType().Assembly;//Get the Assembly assembly of the class through its type object
        Console.WriteLine("Output the name of the obtained assembly:{0}",myassem.FullName);
        Type[] types = myassem.GetTypes();
        foreach (var type in types)
        {
            Console.WriteLine("Output us type The referenced assembly classes are:{0}",type);
        }
        Console.ReadKey();

    }
}
}

Operation results:

We will find that the names of our program and the classes contained in it are printed

1.1. How to load assemblies?

1,Assembly assembly1 = Assembly.Load(“SomeAssembly”); When an assembly is loaded based on its name, it looks for an assembly that matches its name in the local directory and the global assembly cache directory.
2. Assembly assembly2 = assembly. Loadfrom (@ "c:\xx\xx\xx\SomeAssembly.dll") / / the parameter here is the full pathname of the assembly, which will not be searched elsewhere.

1.2 use of assembly objects

1. Get the full name of the assembly string name = assembly1.FullName;
2. Traverse the types defined in the assembly Type[] types = theAssembly.GetTypes();
foreach(Type definedType in types){
//
}
3. Traverse all the features defined in the assembly
Attribute[] definedAttributes = Attribute.GetCustomAttributes(someAssembly);

2. What are 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.
A program structure to which features are applied is called a target
Programs designed to retrieve and use metadata (object browsers) are called feature consumers
. NET subscribes to many features, and we can also declare custom features

2.1 creating and using properties

We apply features to the program structure in the source code;
The compiler obtains the source code and generates metadata from the feature, and then puts the metadata into the assembly;
The consumer program can obtain the metadata of features and other components in the program. Note that the compiler has both production and consumption features.

As for the naming specification of features, feature names use Pascal naming method (initial capitalization) and end with Attribute suffix. When applying features to targets, we can not use suffix. For example, for SerializableAttribute and MyAttributeAttribute, we can use Serializable and MyAttribute when we apply them to structures.

2.2 application characteristics

Let's first look at how to use features. The purpose of the feature is to tell the compiler to embed a set of metadata of the program structure into the assembly. We can do this by applying features to the structure.
Place a property fragment in front of the structure to apply the property;
The feature fragment is surrounded by square brackets, and the feature fragment includes the feature name and the parameter list of the feature;
The structure applied with characteristics becomes characteristic decoration.

Case 1
[Serializable] / / feature
public class MyClass{
// ...
}
Case 2
[MyAttribute("Simple class", "Version 3.57")] / / features with parameters
public class MyClass{
//...
}

3.Obsolete - >. Net predefined features

A program may go through multiple releases in its life cycle, and it is likely to last for many years. In the second half of the program life cycle, programmers often need to write new methods with similar functions to replace the old methods. For a variety of reasons, you may no longer use old code that calls outdated old methods. You just want to call the new method with the newly written code. The old method cannot be deleted because some old code also uses the old method, so how to prompt the programmer to use the new code? You can use the Obsolete property to mark the program structure as out of date and display useful warning messages when the code is compiled.
class Program{
[Obsolete("Use method SuperPrintOut")] / / apply the attribute to the method
static void PrintOut(string str){
Console.WriteLine(str);
}
[Obsolete("Use method SuperPrintOut", true)] / / the second parameter of this feature indicates whether it should be marked as an error, not just a warning.
static void PrintOut(string str){
Console.WriteLine(str);
}
static void Main(string[] args){
PrintOut("Start of Main");
}
}

Test_Character.class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_Character
{
    class Program
    {
        [Obsolete("This method is out of date NewMethod To replace")]//The attribute is applied to the method, and the obsolete attribute is used to represent a method
        //[Obsolete("this method is obsolete, use NewMethod instead", false)] / / this feature adds a bool value. When the bool value is true, the method will be reported as an error
        static  void OldMethod()
        {
            Console.WriteLine("OldMethod");
        }
        static void NewMethod()
        {
            Console.WriteLine("NewMethod");
        }
        static void Main(string[] args)
        {
            OldMethod();
        }
    }
}

4. Conditional feature

The Conditional feature allows us to include or cancel all calls to a particular method. Apply the Conditional attribute to the method declaration and use the compiler as a parameter.
The CIL code that defines the method itself is always included in the assembly, but the calling code is inserted or ignored.
#define DoTrace

class Program{
[Conditional("DoTrace")]
static void TraceMessage(string str){
Console.WriteLine(str);
}
static void Main(){
TraceMessage("Start of Main");
Console.WriteLine("Doing work in Main.")
TraceMessage("End of Main");
}
}

be careful:

The namespace of the conditional attribute is:

using System.Diagnostics;// Namespace of conditional

So when we use this feature, we must not forget to refer to the corresponding namespace

Suppose we have two static global methods, Test1 and Test2. When we call the two methods, we will output two results, but when we use Conditional and set it through macros, we can ignore the functions marked with Conditional.

For example:

//#define IsTest// defines a macro to specify the function we marked, and it will not be invoked if it is annotated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;//Namespace of Conditional

namespace Test_Character
{
    class Program
    {
        [Conditional("IsTest")]
        static void Test1()
        {
            Console.WriteLine("Test1");
        }
        static void Test2()
        {
            Console.WriteLine("Test2");
        }
       
        static void Main(string[] args)
        {
            Test1();
            Test2();
            Test1();
        }
    }
}

Output result of comment macro:

Output of uncommented macro:

Test1 and Test2 methods will still be compiled into the program, but the compiler will detect whether the corresponding macro is defined. If the macro is defined, test1 method will not be called. If the specified macro is not defined, test1 method will be called.

5. Caller information characteristics

The caller information feature can access source code information such as file path, number of lines of code, name of calling member, etc.
The three attribute names are CallerFilePath,CallerLineNumber, and CallerMemberName

File representing the caller: CallerFilePath

Number of lines of code representing the caller: CallerLineNumber

Method member name representing the caller: CallerMemberName

These properties can only be used for optional parameters in methods
For example:

#define IsTest / / a macro is defined. If it is commented out, it will not be called
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.CompilerServices;//Namespace of Conditional

namespace Test_Character
{
    class Program
    {
       public static void PrintOut(string message,[CallerFilePath] string filename="",
           [CallerLineNumber]int lineNumber = 0,[CallerMemberName]string callingMember="")
       {
	    Console.WriteLine("Message:"+message);
	    Console.WriteLine("Line :"+lineNumber);
	    Console.WriteLine("Called from:"+callingMember);
	    Console.WriteLine("Message :"+message);
        }
        static void Main(string[] args)
        {
            PrintOut("123");
        }
    }
}

The operation results are as follows:

6. Contact with work practice:

In fact, the above content is also summarized by previous bloggers through online learning. At present, the main job responsibilities of bloggers are related to the packaging process of the project, and most of them use the knowledge between C# and a large number of file operations. Therefore, after completing some chapters, bloggers may plan to start from packaging tools, extension tools, AssetBundle Summarize the packaging principle, process and packaging related knowledge to introduce you. However, this cycle may also be relatively long. On the one hand, for work reasons, I may not be able to spend too much time writing articles for a long time. On the other hand, if I summarize my understanding of the framework, I prefer to wait until it can be accurately stated before I consider expressing the detailed process of the packaging process through articles, On the one hand, I don't want to mislead fans. On the other hand, to copy the content for the efficiency of the article, it's better to express it in my own way, which is easier to understand.

7. Remarks:

I've known a friend's sentence before. There are many bosses in CSDN and many excellent articles. Everyone's level is different and the effect can be expressed is different, but it's good to present their own expression in the form of articles.

Therefore, if you like this simple, chapter content statement, or as a circle of friends in your daily work, you are welcome to pay attention.

If bloggers want to know more about this chapter, they can comment. After this chapter is over, I will make the corresponding content in the next plan according to the comment feedback and my ability~

Author: ProMer_Wang

Link: https://blog.csdn.net/qq_43801020/article/details/120279253

This article is promer_ The copyright of Wang's original article belongs to the author. Please indicate the source of the original text for reprint. Welcome to reprint!

Posted by EcLip$e on Mon, 13 Sep 2021 22:30:17 -0700