使用C#反射从字典生成动态对象
本文关键字:动态 对象 字典 反射 使用 | 更新日期: 2023-09-27 18:27:58
我一直在研究C#中的反射,想知道我是否使用带有键值的字典可以使用变量创建对象,该变量包含字典中每个键的名称及其值,那本字典的键值。
我有一个相反的方法,它从字典中提取一个对象,这个字典包含键和类属性及其值,属性的值。
如果可能的话,我想知道该怎么做。
下面是我的方法,它提取一个对象的字典:
protected Dictionary<String, String> getObjectProperty(object objeto)
{
Dictionary<String, String> dictionary = new Dictionary<String, String>();
Type type = objeto.GetType();
FieldInfo[] field = type.GetFields();
PropertyInfo[] myPropertyInfo = type.GetProperties();
String value = null;
foreach (var propertyInfo in myPropertyInfo)
{
if (propertyInfo.GetIndexParameters().Length == 0)
{
value = (string)propertyInfo.GetValue(objeto, null);
value = value == null ? null : value;
dictionary.Add(propertyInfo.Name.ToString(), value);
}
}
return dictionary;
}
如果你已经有了字典,我会避免反思,只使用DynamicObject
例如:
public class DynamicDictionary : DynamicObject
{
private readonly Dictionary<string, object> dictionary;
public DynamicDictionary(Dictionary<string, object> dictionary)
{
this.dictionary = dictionary;
}
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
return dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
dictionary[binder.Name] = value;
return true;
}
}
可按如下方式使用:
dynamic x = new DynamicDictionary(
new Dictionary<string, object> {{"Name", "Peter"}});
Console.WriteLine(x.Name);
我不确定这是否是你想要的,但从你的问题来看,我认为你想在运行时从字典中的类型实例化类型,字典将通过提供键来获得。
如果是这样的话,那么您可以创建以下类,该类将包含将成为您的键的字符串的键值对,以及将表示您的值的类型,这些值将被实例化。
class DictionaryActivator
{
Dictionary<string, Type> Dictionary = new Dictionary<string, Type>();
public DictionaryActivator()
{
Dictionary.Add("MyCar", typeof(Car));
Dictionary.Add("MyHouse", typeof(House));
Dictionary.Add("MyFruit", typeof(Fruit));
Dictionary.Add("MyComputer", typeof(Computer));
}
public T GetInstance<T>(string type, params object[] parameters)
{
if (parameters.Count() == 0)
{
return (T)Activator.CreateInstance(Dictionary[type]);
}
else
{
return (T)Activator.CreateInstance(Dictionary[type], parameters.ToArray());
}
}
}
您还可以创建四个测试类来测试此设置。
class House
{
public int Number = 25;
}
class Car
{
public double Price = 50000;
}
class Fruit
{
public string Name = "Apple";
}
class Computer
{
public string Cpu { get; set; }
public string Gpu { get; set; }
public Computer(string cpu, string gpu)
{
Cpu = cpu;
Gpu = gpu;
}
}
完成后,您可以运行以下代码行从字典中获取所有类型,实例化它们并将它们强制转换为适当的类型。正如您可能注意到的,最后一个Computer示例向您展示了如何将多个参数(在本例中为两个)添加到新创建的实例中,并将其作为object类型的实例返回。
最后,您可以将其强制转换为Computer类型,这样您就可以检查构造函数参数是否实际转到了相应的属性。
class Program
{
static void Main()
{
var source = new DictionaryActivator();
Console.WriteLine(source.GetInstance<Car>("MyCar").Price);
Console.WriteLine(source.GetInstance<House>("MyHouse").Number);
Console.WriteLine(source.GetInstance<Fruit>("MyFruit").Name);
var computer = source.GetInstance<object>("MyComputer", "Fast CPU", "Fast GPU");
Console.WriteLine((computer as Computer).Cpu);
Console.WriteLine((computer as Computer).Gpu);
Console.Read();
}
}
由于ExpandoObject
是一个字典,您可以使用以下扩展函数:
public static object With(this IDictionary<string, object> obj, IDictionary<string,object> additionalProperties)
{
foreach (var name in additionalProperties.Keys)
obj[name] = additionalProperties[name];
return obj;
}
用法:
var dynamicObj = new System.Dynamic.ExpandoObject().With(myDictionary);