之前寫程式碼會經常看到獲得 unity 組件 我也就一直在用也沒了解下背後的秘密 這是記事本寫上了這種用法 今天不知道摸魚不香了 還是閒的蛋疼了 想要了解下這個背後的原理
[UIControl("normal/Back/Title/Text")]
protected Text TitleText;
探秘階段一#
先找打實現的方法
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;
}
}
第一印象 是一個繼承了 c# 的特性
然後就是這是如何獲取的了?我當時是一頭霧水
貌似就要了解下 c# 特性了
探秘階段 二#
看這位老師介紹說 還挺形象的 簡單地說,Attribute 就是一種 “附著物”—— 就像牡蠣吸附在船底或礁石上一樣
Attribute 是一種可由用戶自有定義的修飾符(Modifier),可以用來修飾各種需要被修飾的目標。我們可以對類、以及 C# 程序集中的成員進行進一步的描述。
有點像 python 裡面的裝飾器 都是對類 以及方法的 再次描述
與註釋的本質區別就是不會被 丟棄#
Attribute 是程式碼的一部分,它不但不會被編譯器丟棄,而且還會被編譯器編譯進程序集(Assembly)的元數據(Metadata)裡。在程式運行的時候,隨時可以從元數據(元數據:.NET 中元數據是指程序集中的命名空間、類、方法、屬性等信息,這些信息是可以通過 Reflection 讀取出來的。)中提取提取出這些附加信息,並以之決策程式的運行。
下面是上面老師給出一個簡單示例#
比如我們寫一個關於人的類 Person,該類可以對人的屬性以及某些行為 (方法) 進行描述。那么如果我們要對人類進行進一步描述呢?比如人這個類是屬於動物的靈長類動物 當然有人會說我們可以為這個 Person 類去寫一個靈長動物類的父類,再用人類去繼承這個類去解決。但是我們要求的是僅僅是描述性的,就是對這個人類進行進一步的描述,而在實際操作中不需要去操作。這樣的情況我們就可以用特性的概念去解決,特性簡而言之就是程序集的特定程式元素所具有的另外的性質。
//先定義一個人類Person類
class Person
{
//人的姓名儲存字段和屬性
private string name;
public string Name
{
set { name = value; }
get { return name; }
}
//人的年齡儲存字段和屬性
private int age;
public int Age
{
set { age = value; }
get { return age; }
}
//人的性別儲存字段和屬性
private char sex;
public char Sex
{
set { sex = value; }
get { return sex; }
}
//人的打招呼方法
public void SayHello()
{
Console.WriteLine($"大家好,我叫{this.Name},我今年{this.Age}歲了,我的性別是{this.Sex}");
}
}
後再定義一個靈長類的特徵
//定義動物的特性類AnimalAttribute類繼承於Attribute(特性)
class AnimalAttribute : Attribute
{
//字段和屬性描述是否是靈長類
private bool isPrimate;
public bool IsPrimate
{
set { isPrimate = value; }
get { return isPrimate; }
}
}
對人類進行動物類描述。即在人類的定義前面加:
[Animal (IsPrimate = true)] // 為人類加特性,指定人類是靈長類。
[Animal(IsPrimate = true)]
class Person
後面我們即可通過反射的方法來回去特性
//聲明特性對象,並通過Attribute類的靜態方法GetCustomAttribute()獲得人類的在動物類的特性,並賦值給特性對象
Attribute att1 = Attribute.GetCustomAttribute(typeof(Person), typeof(AnimalAttribute));
//將特性對象轉化為動物特性對象
AnimalAttribute animalAtt = att1 as AnimalAttribute;
//檢查轉化是否成功如果成功則打印這個特性對象的是否是靈長類的屬性。
if (animalAtt != null)
{
Console.WriteLine("人類是否是靈長類:{0}", animalAtt.IsPrimate);
}
Console.ReadKey();
舉一反三#
我想到之前遇到一個問題 讓一個方法返回字符串 變成大寫的 完全就可以通過這樣的方式來進行調整
有勞 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
允許你在方法執行的不同階段插入自定義的程式碼。
OnSuccess 方法: OnSuccess
是在方法成功完成後被調用的方法。你可以在這個方法中訪問方法的返回值並進行操作。在上面的示例中,我們使用 OnSuccess
方法將方法返回的字符串轉換為大寫。
探秘階段 三#
知道原理以後全局搜索下如何獲取自然 而然找到了初始化面板控件裡面
有對 UI 的操作 疑惑就解除了
此文由 Mix Space 同步更新至 xLog 原始鏈接為 http://121.41.123.51:2333/posts/categories/3