Reflection 使你能够获取有关加载的程序集和其中定义的类型的信息,如类、接口和值类型。 程序集包含模块、模块包含类型,而类型包含成员。反射提供封装程序集、模块和类型的对象。可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了特性,可以利用反射来访问它们。
反射的基础用法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Reflection;
public class Test : MonoBehaviour
{
private void Start()
{
// 获取类型
Type t = Type.GetType("Person");
t = typeof(Person);
// 所有成员
MemberInfo[] all = t.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static
| BindingFlags.Instance | BindingFlags.DeclaredOnly);
// 字段
FieldInfo[] fi = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (var v in fi)
{
Debug.Log(v.Name);
}
// 属性
PropertyInfo[] pi = t.GetProperties();
foreach (var v in pi)
{
Debug.Log(v.Name);
}
// 方法
MethodInfo[] mi = t.GetMethods();
foreach (var v in mi)
{
Debug.Log(v.Name);
}
// 动态创建对象
Person p = Activator.CreateInstance(t, new object[] { "sh" }) as Person;
PropertyInfo ppi = t.GetProperty("Age");
ppi.SetValue(p, 25, null);
MethodInfo pmi = t.GetMethod("IsYong");
Debug.Log("Age:" + p.Age + " IsYong:" + pmi.Invoke(p, null));
}
}
public class Person
{
private string name;
public int Age { get; set; }
public Person(string name)
{
this.name = name;
}
[Obsolete("一个Obsolete特性的使用")]
public bool IsYong()
{
return Age <= 18;
}
}
|
在下面的例子中,使用反射动态向List中添加数据,代码在Unity中通过
BaseTable.cs
1
2
3
4
5
6
7
8
9
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseTable : MonoBehaviour
{
public string excelPath;
public string tableName;
}
|
ItemTable.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ItemTable : BaseTable
{
public List<ItemData> dataList = new List<ItemData>();
}
[System.Serializable]
public class ItemData
{
public int X;
public int Y;
}
|
BaseTableEditor.cs 文件放在 Editor 目录下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;
[CustomEditor(typeof(BaseTable), true)]
public class BaseTableEditor : Editor {
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Load"))
{
Type targetType = target.GetType();
FieldInfo dataListField = targetType.GetField("dataList");
Type listType = dataListField.FieldType;
Type dataType = listType.GetGenericArguments()[0];
object obj = Activator.CreateInstance(dataType, null);
foreach (var v in dataType.GetFields())
{
v.SetValue(obj, 1);
}
listType.GetMethod("Add").Invoke(dataListField.GetValue(target), new object[] { obj });
}
}
}
|