C#通过反射实现Dictionary初始化任意类型对象

C#通过反射实现Dictionary初始化任意类型对象

写在前面

这段时间写代码,经常需要用字典来初始胡一个对象的成员变量。便有了如下需求:用一个函数实现字典初始化任意类型对象,包括嵌套类。 看了网上很多帖子,感觉写的都太简单了,不适用。于是自己下场写了一个。

方法

核心思想就是:通过object.GetType()获取object的实际类型。通过Type.GetFields()获取类下面的所有公共字段,type.GetProperties()获取类下面的所有公共属性。对值类型直接SetValue赋值,对于类类型用Activator.CreateInstance调用默认构造函数创建对象(因此嵌套类成员需要有默认构造函数),然后递归初始化嵌套类成员。之所以要单独处理String类型,正是因为String没有默认构造函数。

private static void CreateObject(object obj, Dictionary<string, string> dic)
{
    if (obj == null) { return; }

    Type type = obj.GetType();
    //	返回当前 Type 的所有公共字段。
    foreach (var number in type.GetFields())
    {
        //获取字段类型
        Type curType = number.FieldType;
        //对于值类型
        if (curType.IsValueType)
        {
            //Console.WriteLine("值类型" + number.Name);
            number.SetValue(obj, Convert.ChangeType(dic[number.Name], number.FieldType));
            continue;
        }
        //对于string类型
        else if (curType.IsClass && curType == typeof(String))//单独处理字符串,因为字符出没有默认构造函数
        {
            //Console.WriteLine("String类型" + number.Name);
            number.SetValue(obj, Convert.ChangeType(dic[number.Name], number.FieldType));
            continue;
        }
        //对于class类型
        else if (curType.IsClass)
        {
            //Console.WriteLine("MyObject类型" + number.Name);
            if (number.GetValue(obj) == null)
            {
                Type objType = number.FieldType;
                object curObj = Activator.CreateInstance(objType);
                number.SetValue(obj, curObj);
            }
            //递归
            CreateObject(number.GetValue(obj), dic);
        }
    }
    //	 返回当前 Type 的所有公共属性。
    foreach (var number in type.GetProperties())
    {
        //Console.WriteLine("属性类型" + number.Name);
        number.SetValue(obj, Convert.ChangeType(dic[number.Name], number.PropertyType));
    }
}

测试

可以看到我们使用用一个函数CreateObject函数分别初始化了嵌套类C和类D的对象。
在这里插入图片描述

 public class A
    {
        public int a_x;
        public string a_y;
        private String a_z;
    }
    public class B
    {
        public int b_x;
        public double b_y { get; set; }
    }
    public class C
    {
        public A a;
        public B b;
    }

    public class D
    {
        public int x;
        public int y;
    }

    public static void Main()
    {
        C c = new C();
        Dictionary<string, string> dic = new Dictionary<string, string>();
        dic.Add("a_x", "1");
        dic.Add("a_y", "2");
        dic.Add("b_x", "3");
        dic.Add("b_y", "4");
        CreateObject(c, dic);
        Console.WriteLine("c.a.a_x=" + c.a.a_x);
        Console.WriteLine("c.a.a_y=" + c.a.a_y);
        Console.WriteLine("c.a.b_x=" + c.b.b_x);
        Console.WriteLine("c.a.b_y=" + c.b.b_y);

        D d = new D();
        dic = new Dictionary<string, string>();
        dic.Add("x", "1");
        dic.Add("y", "2");
        CreateObject(d, dic);
        Console.WriteLine("d.x=" + d.x);
        Console.WriteLine("d.y=" + d.y);
    }

写在后面

听出来2b配音是三笠(ミカサ)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值