今天打球的小姐姐格外,,,
小姐姐為了感謝我最近的付出,邀請我一塊打球,那我必須得把把贏她(鋼鐵直男的氣勢不能丟),不能給程式員丟臉,我被眼前的球晃的好暈🙈,很快小姐姐也沒力氣了,坐在了地上,說最近被反射搞得好迷糊🙈,

那我肯定不能慣著她😎,反射下,看小姐姐的腳本里都寫了啥!!😎😎😎💛😻😻
Unity C# 游戲開發 反射 Reflection 案例講解(圖文詳細,帶原始碼)
- 今天打球的小姐姐格外,,,
- 一、反射是什么?
- 二、反射怎么用?
- 1.要反射的目標腳本內容
- 2.反射的實際應用
- 1).獲取建構式的所有引數及引數的資料型別
- 2).通過反射獲取屬性
- 3).查看類中的公開方法
- 4).查看類中的公開欄位
- 5).通過反射用建構式動態生成物件
- 6).通過反射用Activator靜態生成物件
- 7).通過反射,創建物件,給欄位,屬性賦值,呼叫方法
- 三、原始碼
- 總結
- 著作權宣告
一、反射是什么?
我們先來個官方的解釋:這是官方的檔案檔案鏈接
反射提供了描述程式集、模塊和型別的物件(型別為Type),您可以使用反射動態創建型別的實體,將型別系結到現有物件,或從現有物件獲取型別并呼叫其方法或訪問其欄位和屬性,如果您在代碼中使用屬性,反射使您能夠訪問它們,
講完之后,小姐姐的狀態是這樣的:

相信大家也有這種感覺,這都說的是啥?
用我自己的理解來解釋:反射可以讓你知道一個程式集里面的建構式,欄位,屬性,方法,等等,知道了這些,你就可以去創建相應的物件了,
接下來就用我偷偷從小姐姐那拷過來的腳本來練練手,
二、反射怎么用?
我們直接用小姐姐的腳本來一塊學習下
1.要反射的目標腳本內容
下面就是小姐姐腳本的全部內容,里面有欄位,屬性,建構式,方法,我們可以先不看里面寫的啥,一會用反射就都可以看到啦!😜
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReflectionTest
{
/// <summary>
/// 排名
/// </summary>
public int ranking;
/// <summary>
/// 名字
/// </summary>
private string m_name;
/// <summary>
/// 長度
/// </summary>
private string m_length;
/// <summary>
/// 形狀
/// </summary>
private string m_shape;
#region 建構式
public ReflectionTest(string name, string length)
{
this.m_name = name;
this.m_length = length;
}
public ReflectionTest(string name,string shape, string length)
{
this.m_name = name;
this.m_shape = shape;
this.m_length = length;
}
public ReflectionTest(string shape)
{
this.m_shape = shape;
}
public ReflectionTest()
{
}
#endregion
#region 屬性
/// <summary>
/// 名字
/// </summary>
public string Name
{
get => m_name;
set => m_name = value;
}
/// <summary>
/// 長度
/// </summary>
public string Length
{
get => m_length;
set => m_length = value;
}
/// <summary>
/// 形狀
/// </summary>
public string Shape
{
get => m_shape;
set => m_shape = value;
}
#endregion
/// <summary>
/// 資訊列印出來
/// </summary>
public void ShowContent()
{
Debug.Log("姓名:" + m_name + "\n" + "形狀:" + m_shape + "---" + "長度:" + m_length);
}
/// <summary>
/// 列印排名
/// </summary>
public void ShowRanking()
{
Debug.Log("排名是:"+ranking);
}
/// <summary>
/// 要開始發動啦!!
/// </summary>
public void StartMove()
{
Debug.Log(m_name+"要開始發動啦!!");
}
}
💥💥接下來就讓我們大展身手
2.反射的實際應用
我就舉幾個比較常用的方法,拋磚引玉
感興趣的小伙伴可以根據官方檔案去做更多的實踐,要永遠相信,官方檔案是最全面的,檔案鏈接在上面發了,
首先我們創建個腳本,掛載到空物體上

在腳本中實體化要反射的小姐姐腳本,
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using Object = UnityEngine.Object;
/// <summary>
/// 反射的相關測驗
/// </summary>
public class FindOfReflection : MonoBehaviour
{
private ReflectionTest reflectionTest;
private void Awake()
{
reflectionTest = new ReflectionTest();
}
}
1).獲取建構式的所有引數及引數的資料型別
private void Start()
{
SeeConstructor();
}
/// <summary>
/// 獲取建構式的所有引數及引數的資料型別
/// </summary>
private void SeeConstructor()
{
//獲取reflectionTest的Type
Type type = reflectionTest.GetType();
//通過Type獲取這個類的所有建構式資訊
ConstructorInfo[] constructorArray = type.GetConstructors();
foreach (ConstructorInfo constructorInfo in constructorArray)
{
//獲取每個建構式的所有引數
ParameterInfo[] parameterArray = constructorInfo.GetParameters();
foreach (ParameterInfo parameterInfo in parameterArray)
{
Debug.Log("資料型別:"+parameterInfo.ParameterType.ToString()+"\n"+"引數名字:"+parameterInfo.Name);
}
}
}
🌵執行結果如下

2).通過反射獲取屬性
private void Start()
{
SeeProperty();
}
/// <summary>
/// 通過反射獲取屬性
/// </summary>
private void SeeProperty()
{
//獲取reflectionTest的Type
Type type = reflectionTest.GetType();
//獲取所有屬性資訊
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
//列印出來屬性的名字
Debug.Log("屬性:"+propertyInfo.Name);
}
}
🌵執行結果如下

3).查看類中的公開方法
private void Start()
{
SeePublicMethod();
}
/// <summary>
/// 查看類中的公開方法
/// </summary>
private void SeePublicMethod()
{
Type type = reflectionTest.GetType();
//通過type獲取所有公開方法的資訊
MethodInfo[] methodInfos = type.GetMethods();
foreach (MethodInfo methodInfo in methodInfos)
{
Debug.Log("公開方法的回傳型別:"+methodInfo.ReturnType+"---"+"方法的名字:"+methodInfo.Name);
}
}
🌵執行結果如下

4).查看類中的公開欄位
private void Start()
{
SeePublicField();
}
/// <summary>
/// 查看類中的公開欄位
/// </summary>
private void SeePublicField()
{
Type type = reflectionTest.GetType();
//通過type獲取所有公開的欄位的資訊
FieldInfo[] fieldInfos = type.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
Debug.Log("公開的欄位的名字:"+fieldInfo.Name);
}
}
🌵執行結果如下

中斷一下,我感覺這小姐姐的腳本不對勁,你們回頭看下反射出來的資料,難道,,😱
5).通過反射用建構式動態生成物件
那我們就將計就計,生成幾個符合小姐姐的物件吧
private void Start()
{
CreatObjectByConstruct();
}
/// <summary>
/// 通過反射用建構式動態生成物件
/// </summary>
private void CreatObjectByConstruct()
{
Type type = reflectionTest.GetType();
Type[] typeArray ={typeof(string), typeof(string),typeof(string)};
//根據建構式引數型別來獲取建構式
ConstructorInfo constructorInfo = type.GetConstructor(typeArray);
//要傳入的引數
object[] objectArray={"王二","蘑菇","8cm"};
//呼叫建構式來生成物件
object obj = constructorInfo.Invoke(objectArray);
//呼叫列印方法,看是否有輸出
((ReflectionTest)obj).ShowContent();
}
🌵執行結果如下

6).通過反射用Activator靜態生成物件
再來一個!
private void Start()
{
CreatObjByActivator();
}
/// <summary>
/// 通過反射用Activator靜態生成物件
/// </summary>
private void CreatObjByActivator()
{
Type type = reflectionTest.GetType();
object[] objects = {"張三","阿姆斯特朗回旋炮", "22cm"};
object obj = Activator.CreateInstance(type, objects);
//呼叫列印方法,看是否有輸出
((ReflectionTest)obj).ShowContent();
}
🌵執行結果如下

??到這里有的C友肯定要說,不懂就問,什么是阿姆斯特朗回旋炮啊???
就是這貨

7).通過反射,創建物件,給欄位,屬性賦值,呼叫方法
最后我們再來生成物件并修改相應的內容吧
private void Start()
{
CreatAndSet();
}
/// <summary>
/// 通過反射,創建物件,給欄位,屬性賦值,呼叫方法
/// </summary>
private void CreatAndSet()
{
Type type = reflectionTest.GetType();
//創建物件
object obj = Activator.CreateInstance(type);
//通過名字獲取欄位
FieldInfo fieldInfo = type.GetField("ranking");
//給欄位賦值
fieldInfo.SetValue(obj,1);
//獲取所有屬性的資訊
PropertyInfo[] propertyInfos = type.GetProperties();
string[] strings ={"李四", "阿姆斯特朗回旋炮", "33cm"};
//依次給屬性屬性賦值
for (int i = 0; i < propertyInfos.Length; i++)
{
propertyInfos[i].SetValue(obj,strings[i],null);
}
//根據名字找到方法的資訊
MethodInfo methodInfo = type.GetMethod("StartMove");
//執行方法
methodInfo.Invoke(obj, null);
//根據名字找到方法的資訊
MethodInfo methodInfo2 = type.GetMethod("ShowRanking");
//執行方法
methodInfo2.Invoke(obj, null);
}
🌵執行結果如下

三、原始碼
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using Object = UnityEngine.Object;
/// <summary>
/// 反射的相關測驗
/// </summary>
public class FindOfReflection : MonoBehaviour
{
private ReflectionTest reflectionTest;
private void Awake()
{
reflectionTest = new ReflectionTest();
}
private void Start()
{
SeeConstructor();
SeeProperty();
SeePublicMethod();
SeePublicField();
CreatObjectByConstruct();
CreatObjByActivator();
CreatAndSet();
}
/// <summary>
/// 獲取建構式的所有引數及引數的資料型別
/// </summary>
private void SeeConstructor()
{
//獲取reflectionTest的Type
Type type = reflectionTest.GetType();
//通過Type獲取這個類的所有建構式資訊
ConstructorInfo[] constructorArray = type.GetConstructors();
foreach (ConstructorInfo constructorInfo in constructorArray)
{
//獲取每個建構式的所有引數
ParameterInfo[] parameterArray = constructorInfo.GetParameters();
foreach (ParameterInfo parameterInfo in parameterArray)
{
Debug.Log("資料型別:" + parameterInfo.ParameterType.ToString() + "\n" + "引數名字:" + parameterInfo.Name);
}
}
}
/// <summary>
/// 通過反射獲取屬性
/// </summary>
private void SeeProperty()
{
//獲取reflectionTest的Type
Type type = reflectionTest.GetType();
//獲取所有屬性資訊
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
//列印出來屬性的名字
Debug.Log("屬性:" + propertyInfo.Name);
}
}
/// <summary>
/// 查看類中的公開方法
/// </summary>
private void SeePublicMethod()
{
Type type = reflectionTest.GetType();
//通過type獲取所有公開方法的資訊
MethodInfo[] methodInfos = type.GetMethods();
foreach (MethodInfo methodInfo in methodInfos)
{
Debug.Log("公開方法的回傳型別:" + methodInfo.ReturnType + "---" + "方法的名字:" + methodInfo.Name);
}
}
/// <summary>
/// 查看類中的公開欄位
/// </summary>
private void SeePublicField()
{
Type type = reflectionTest.GetType();
//通過type獲取所有公開的欄位的資訊
FieldInfo[] fieldInfos = type.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
Debug.Log("公開的欄位的名字:" + fieldInfo.Name);
}
}
/// <summary>
/// 通過反射用建構式動態生成物件
/// </summary>
private void CreatObjectByConstruct()
{
Type type = reflectionTest.GetType();
Type[] typeArray = {typeof(string), typeof(string), typeof(string)};
//根據建構式引數型別來獲取建構式
ConstructorInfo constructorInfo = type.GetConstructor(typeArray);
//要傳入的引數
object[] objectArray = {"王二", "蘑菇", "8cm"};
//呼叫建構式來生成物件
object obj = constructorInfo.Invoke(objectArray);
//呼叫列印方法,看是否有輸出
((ReflectionTest) obj).ShowContent();
}
/// <summary>
/// 通過反射用Activator靜態生成物件
/// </summary>
private void CreatObjByActivator()
{
Type type = reflectionTest.GetType();
object[] objects = {"張三", "阿姆斯特朗回旋炮", "22cm"};
object obj = Activator.CreateInstance(type, objects);
//呼叫列印方法,看是否有輸出
((ReflectionTest) obj).ShowContent();
}
/// <summary>
/// 通過反射,創建物件,給欄位,屬性賦值,呼叫方法
/// </summary>
private void CreatAndSet()
{
Type type = reflectionTest.GetType();
//創建物件
object obj = Activator.CreateInstance(type);
//通過名字獲取欄位
FieldInfo fieldInfo = type.GetField("ranking");
//給欄位賦值
fieldInfo.SetValue(obj, 1);
//獲取所有屬性的資訊
PropertyInfo[] propertyInfos = type.GetProperties();
string[] strings = {"李四", "阿姆斯特朗回旋炮", "33cm"};
//依次給屬性屬性賦值
for (int i = 0; i < propertyInfos.Length; i++)
{
propertyInfos[i].SetValue(obj, strings[i], null);
}
//根據名字找到方法的資訊
MethodInfo methodInfo = type.GetMethod("StartMove");
//執行方法
methodInfo.Invoke(obj, null);
//根據名字找到方法的資訊
MethodInfo methodInfo2 = type.GetMethod("ShowRanking");
//執行方法
methodInfo2.Invoke(obj, null);
}
}
最后說個秘密,我有個C友叫李四,🙈🙈🙈
總結
歡迎大佬多多來給萌新指正,歡迎大家來共同探討,
如果各位看官覺得文章有點點幫助,跪求各位給點個“一鍵三連”,謝啦~
宣告:本博文章若非特殊注明皆為原創原文鏈接
https://blog.csdn.net/Wrinkle2017/article/details/119651165
————————————————————————————————
著作權宣告
著作權宣告:本博客為非營利性個人原創
所刊登的所有作品的著作權均為本人所擁有
本人保留所有法定權利,違者必究!
對于需要復制、轉載、鏈接和傳播博客文章或內容的
請及時和本博主進行聯系
對于經本博主明確授權和許可使用文章及內容的
使用時請注明文章或內容出處并注明網址
轉載請附上原文出處鏈接及本宣告
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293828.html
標籤:其他
上一篇:Pygame制作跳躍小球小游戲
下一篇:實作三子棋
