反射指程序可以访问、检测和修改它本身状态或行为的一种能力,可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
反射用途:
- 它允许在运行时查看特性信息。
- 它允许审查集合中的各种类型,以及实例化这些类型。
- 它允许延迟绑定的方法和属性。
- 它允许在运行时创建新类型,然后使用这些类型执行一些任务。
反射的优点:
- 1、反射提高了程序的灵活性和扩展性。
- 2、降低耦合性,提高自适应能力。
- 3、它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
反射的缺点:
- 1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
- 2、使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
1.对已有类进行反射
测试数据类:
public enum TestEnum
{
TEST1=0,
TEST2=1,
}
public class TestClass
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsVip { get; set; }
public float LineTime { get; set; }
public TestEnum TestType { get; set; }
public List<string> TestStrList { get; set; }
public List<Player> TestPlayerList { get; set; }
}
public class Player
{
public int ID { set; get; }
public string Name { set; get; }
}
/// <summary>
/// 对已有类进行反射
/// </summary>
private void TestReflection1()
{
TestClass testClass = new TestClass()
{
ID = 1001,
Name = "测试one",
IsVip = false,
TestStrList = new List<string>(),
TestPlayerList = new List<Player>(),
};
testClass.TestStrList.Add("test1");
testClass.TestStrList.Add("test2");
testClass.TestStrList.Add("test3");
for (int i = 0; i < 3; i++)
{
Player player = new Player();
player.ID = i + 1;
player.Name = "玩家" + i;
testClass.TestPlayerList.Add(player);
}
Debug.Log(GetMemberValue(testClass, "ID") + " " + GetMemberValue(testClass, "Name"));
object list = GetMemberValue(testClass, "TestStrList");
int listCount = System.Convert.ToInt32(list.GetType().InvokeMember("get_Count",
BindingFlags.Default | BindingFlags.InvokeMethod, null, list, new object[] { }));
for (int i = 0; i < listCount; i++)
{
object item = list.GetType().InvokeMember("get_Item", BindingFlags.Default |
BindingFlags.InvokeMethod, null, list, new object[] { i });
Debug.Log("List: " + item);
}
object list2 = GetMemberValue(testClass, "TestPlayerList");
int listCount2 = System.Convert.ToInt32(list2.GetType().InvokeMember("get_Count", BindingFlags.Default |
BindingFlags.InvokeMethod, null, list2, new object[] { }));
for (int i = 0; i < listCount2; i++)
{
object item = list2.GetType().InvokeMember("get_Item", BindingFlags.Default |
BindingFlags.InvokeMethod, null, list2, new object[] { i });
object id = GetMemberValue(item, "ID");
object name = GetMemberValue(item, "Name");
Debug.Log(id + " " + name);
}
}
获取 每个属性值
Type type = obj.GetType();
MemberInfo[] members = type.GetMember(memberName, bindingFlags);
switch (members[0].MemberType)
{
//变量
case MemberTypes.Field:
return type.GetField(memberName, bindingFlags).GetValue(obj);
//属性
case MemberTypes.Property:
return type.GetProperty(memberName, bindingFlags).GetValue(obj);
default:
return null;
}
2.根据已知数据 ,进行反射
object obj = CreateClass("TestClass");
PropertyInfo info = obj.GetType().GetProperty("ID");
SetValue(info, obj, "18", "int");
PropertyInfo nameInfo = obj.GetType().GetProperty("Name");
SetValue(nameInfo, obj, "ojbk", "string");
PropertyInfo boolInfo = obj.GetType().GetProperty("IsVip");
SetValue(boolInfo, obj, "true", "bool");
PropertyInfo lineInfo = obj.GetType().GetProperty("LineTime");
SetValue(lineInfo, obj, "12.3", "float");
PropertyInfo enumInfo = obj.GetType().GetProperty("TestType");
SetValue(enumInfo, obj, "TEST1", "enum");
Type type = typeof(string);
object list = CreateList(type);
for (int i = 0; i < 3; i++)
{
object addItem = "测试Data" + i;
list.GetType().InvokeMember("Add", BindingFlags.Default | BindingFlags.InvokeMethod, null,
list, new object[] { addItem });// add添加数据
}
obj.GetType().GetProperty("TestStrList").SetValue(obj, list);
//创建自定义List<Class>
object twoList = CreateList(typeof(Player));
for (int i = 0; i < 3; i++)
{
object addItem = CreateClass("Player");
PropertyInfo itemIdInfo = addItem.GetType().GetProperty("ID");
SetValue(itemIdInfo, addItem, "100" + i, "int");
PropertyInfo itemNameInfo = addItem.GetType().GetProperty("Name");
SetValue(itemNameInfo, addItem, "测试Class" + i, "string");
twoList.GetType().InvokeMember("Add", BindingFlags.Default | BindingFlags.InvokeMethod, null,
twoList, new object[] { addItem });
}
obj.GetType().GetProperty("TestPlayerList").SetValue(obj, twoList);
TestClass testInfo = (obj as TestClass);
Debug.Log(testInfo.ID + " " + testInfo.Name + " " + testInfo.IsVip + " " +
testInfo.LineTime + " " + testInfo.TestType);
foreach (string str in testInfo.TestStrList)
{
Debug.Log(str);
}
foreach (Player test in testInfo.TestPlayerList)
{
Debug.Log(test.ID + " " + test.Name);
}
创建 类:
/// <summary>
/// 创建类的实例
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private object CreateClass(string name)
{
object obj = null;
Type type = null;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
Type tempType = asm.GetType(name);
if (tempType != null)
{
type = tempType;
break;
}
}
if (type != null)
{
obj = Activator.CreateInstance(type);
}
return obj;
}
创建List:
private static object CreateList(Type type)
{
Type listType = typeof(List<>);
//确定类型
Type specType = listType.MakeGenericType(new System.Type[] { type });
//创建出list
return Activator.CreateInstance(specType, new object[] { });
}
测试结果: