反转旋木

反转旋木

时代的一粒尘埃,落在个人身上就是一座大山

Encountering interesting code - Reflective component retrieval

Previously, when writing code, I often saw getting Unity components. I have been using it without understanding the secret behind it. This usage is written in the notepad. Today, I don't know why I'm not in the mood to slack off. I want to understand the principle behind it.

    [UIControl("normal/Back/Title/Text")]
    protected Text TitleText;

Exploration Phase 1#

First, find the implementation method.

public class UIControlAttribute : Attribute
{
    public string controlName;
    public System.Type componentType;
    public int baseNum;
    public UIControlAttribute(string controlName,System.Type componentType = null,int baseNum = 0)
    {
        this.controlName = controlName;
        this.componentType = componentType;
        this.baseNum = baseNum;
    }
}

The first impression is that it is an attribute inherited from C#.

Then, how is this obtained? I was confused at that time.

It seems that I need to understand C# attributes.

Exploration Phase 2#

This teacher's introduction says that it is quite vivid. In simple terms, an Attribute is a kind of "attachment" - just like an oyster attached to the bottom of a ship or a reef.

Attribute is a modifier that can be defined by the user, which can be used to modify various targets that need to be modified. We can further describe classes and members in C# programs.

It's a bit like decorators in Python, both of which describe classes and methods again.

The essential difference from comments is that they will not be discarded.#

Attributes are part of the program code. They will not be discarded by the compiler, but will be compiled into the metadata of the program assembly. At runtime, these additional information can be extracted from the metadata (metadata: In .NET, metadata refers to the information of namespaces, classes, methods, properties, etc. in the assembly. This information can be read out through Reflection.) and used to make decisions about the program's execution.

Here is a simple example given by the teacher above#

For example, we write a class Person about a person, which can describe the attributes and certain behaviors (methods) of a person. So how do we further describe the human class? For example, the human class belongs to the primate class of animals. Of course, someone will say that we can write a parent class of the primate class for this Person class, and then use the human class to inherit this class to solve it. But what we require is only descriptive, that is, to further describe this human class, and there is no need to operate in practice. In this case, we can use the concept of attributes to solve it. In short, attributes are additional properties of specific program elements in the program assembly.

		//First define a Person class for the human class
        class Person
        {
            //Field and property to store the name of the person
            private string name;
            public string Name
            {
                set { name = value; }
                get { return name; }
            }

            //Field and property to store the age of the person
            private int age;
            public int Age
            {
                set { age = value; }
                get { return age; }
            }

            //Field and property to store the gender of the person
            private char sex;
            public char Sex
            {
                set { sex = value; }
                get { return sex; }
            }

            //Method for greeting
            public void SayHello()
            {
                Console.WriteLine($"Hello, my name is {this.Name}, I am {this.Age} years old, and I am {this.Sex}");
            }
        }

Then define a feature of the primate class.

        //Define the AnimalAttribute class that describes the characteristics of animals, which inherits from Attribute (attribute)
        class AnimalAttribute : Attribute
        {
            //Field and property to describe whether it is a primate
            private bool isPrimate;
            public bool IsPrimate
            {
                set { isPrimate = value; }
                get { return isPrimate; }
            }
        }

Describe the human class with the animal class. That is, add:

[Animal(IsPrimate = true)] // Add attributes to the human class to specify that the human class is a primate class.

[Animal(IsPrimate = true)] 
class Person

Then we can use the reflection method to get the attributes.

//Declare an attribute object and use the GetCustomAttribute() method of the Attribute class to get the attribute of the human class in the animal class and assign it to the attribute object
            Attribute att1 = Attribute.GetCustomAttribute(typeof(Person), typeof(AnimalAttribute));

            //Convert the attribute object to an animal attribute object
            AnimalAttribute animalAtt = att1 as AnimalAttribute;

            //Check if the conversion is successful. If successful, print the property of whether this attribute object is a primate class.
            if (animalAtt != null)
            {
                Console.WriteLine("Is the human class a primate class: {0}", animalAtt.IsPrimate);
            }
            Console.ReadKey();

Extend the concept#

I remembered a problem I encountered before, which was to make a method return a string in uppercase. It can be completely adjusted through this method.

Please help me write some code, GPT.

using System;
using PostSharp.Aspects;

[Serializable]
public class ToUpperCaseAttribute : MethodInterceptionAspect
{
    public override void OnSuccess(MethodExecutionArgs args)
    {
        if (args.ReturnValue is string returnValue)
        {
            args.ReturnValue = returnValue.ToUpper();
        }
    }
}

public class MyClass
{
    [ToUpperCase]
    public string GetUpperCaseString(string input)
    {
        return input;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var myClass = new MyClass();
        string result = myClass.GetUpperCaseString("Hello, World!");
        Console.WriteLine(result); // Output will be "HELLO, WORLD!"
    }
}

MethodInterceptionAspect allows you to insert custom code at different stages of method execution.

OnSuccess method: OnSuccess is called after the method is successfully completed. You can access the return value of the method and perform operations in this method. In the example above, we use the OnSuccess method to convert the string returned by the method to uppercase.

Exploration Phase 3#

After understanding the principle, I searched for how to obtain the UI naturally and naturally found it in the initialization panel control.

image-20230812141447825

There are operations on UI, and my doubts are resolved.

This article is synchronized and updated to xLog by Mix Space
The original link is http://121.41.123.51:2333/posts/categories/3


Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.