C# 反射-- Reflection

反射指程序可以访问、检测和修改它本身状态或行为的一种能力,可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。

反射用途:

  • 它允许在运行时查看特性信息。
  • 它允许审查集合中的各种类型,以及实例化这些类型。
  • 它允许延迟绑定的方法和属性。
  • 它允许在运行时创建新类型,然后使用这些类型执行一些任务。

反射的优点:

  • 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[] { });
    }

测试结果:

发布了76 篇原创文章 · 获赞 43 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/hnzmdlhc/article/details/98039413