写在前面
这段时间写代码,经常需要用字典来初始胡一个对象的成员变量。便有了如下需求:用一个函数实现字典初始化任意类型对象,包括嵌套类。 看了网上很多帖子,感觉写的都太简单了,不适用。于是自己下场写了一个。
方法
核心思想就是:通过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配音是三笠(ミカサ)