如何从 C# 中的字典创建 class?
How to create a class from a Dictionary in C#?
我写了一个创建字典的方法。我需要将这本字典转换为 class.
词典示例
Dictionary<string, dynamic> myDictionary = new Dictionary<string, dynamic> {
{ "ID1", 12 },
{ "ID2", "Text2"},
{ "ID3", "Text3" }
};
这是需要创建的 class 的示例:
public class Foo
{
public int ID1 { get; set; }
public string ID2 { get; set; }
public string ID3 { get; set; }
}
正如其他人提到的,这种情况很常见,并且肯定需要一个上下文来从更好的角度解决它,因为我怀疑代码库的架构不好。尽管如此,您的问题仍然有效。要解决它,你至少有两种可能:
1.需要开发时间;运行时的可忽略时间 - 只需创建一个函数,将给定字典映射到 class 的实例。示例:
Foo MapDictionaryToFoo(IReadOnlyDictionary<string, dynamic> d)
{
return new Foo
{
ID1 = d[nameof(Foo.ID1)],
ID2 = d[nameof(Foo.ID2)],
ID3 = d[nameof(Foo.ID3)]
};
}
调用示例:
Foo myFoo = MapDictionaryToFoo(myDictionary);
2。需要运行时间;可忽略的开发时间 - 创建一个将给定字典映射到任意 class 的函数,通常使用反射。下面的示例假设您的 class 具有默认构造函数,因此也充当工厂。如果不是这种情况,可以在附加参数中传递现有实例:
T CreateFromDictionary<T>(IReadOnlyDictionary<string, dynamic> d) where T : new()
{
T obj = new T();
foreach (var propertyInfo in typeof(T).GetProperties())
{
propertyInfo.SetValue(obj, d[propertyInfo.Name]);
}
return obj;
}
调用示例:
Foo myFoo = CreateFromDictionary<Foo>(myDictionary);
如果我必须选择一个,我会选择第一种方法,因为我避免了任何反射,这在运行时很耗时。
您的要求没有明确说明,但我猜您正在寻找一种动态类型,其属性的名称映射到字典键。
在这种情况下,您可以使用像这样的简单字典包装器:
class DynamicDictionaryWrapper : DynamicObject
{
protected readonly Dictionary<string,object> _source;
public DynamicDictionaryWrapper(Dictionary<string,object> source)
{
_source = source;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
return (_source.TryGetValue(binder.Name, out result));
}
}
你可以这样使用:
public static void Main()
{
var myDictionary = new Dictionary<string, dynamic> {
{ "ID1", 12 },
{ "ID2", "Text2"},
{ "ID3", "Text3" }
};
dynamic myObject = new DynamicDictionaryWrapper(myDictionary);
Console.WriteLine(myObject.ID1);
Console.WriteLine(myObject.ID2);
Console.WriteLine(myObject.ID3);
}
输出:
12
Text2
Text3
我写了一个创建字典的方法。我需要将这本字典转换为 class.
词典示例
Dictionary<string, dynamic> myDictionary = new Dictionary<string, dynamic> {
{ "ID1", 12 },
{ "ID2", "Text2"},
{ "ID3", "Text3" }
};
这是需要创建的 class 的示例:
public class Foo
{
public int ID1 { get; set; }
public string ID2 { get; set; }
public string ID3 { get; set; }
}
正如其他人提到的,这种情况很常见,并且肯定需要一个上下文来从更好的角度解决它,因为我怀疑代码库的架构不好。尽管如此,您的问题仍然有效。要解决它,你至少有两种可能:
1.需要开发时间;运行时的可忽略时间 - 只需创建一个函数,将给定字典映射到 class 的实例。示例:
Foo MapDictionaryToFoo(IReadOnlyDictionary<string, dynamic> d)
{
return new Foo
{
ID1 = d[nameof(Foo.ID1)],
ID2 = d[nameof(Foo.ID2)],
ID3 = d[nameof(Foo.ID3)]
};
}
调用示例:
Foo myFoo = MapDictionaryToFoo(myDictionary);
2。需要运行时间;可忽略的开发时间 - 创建一个将给定字典映射到任意 class 的函数,通常使用反射。下面的示例假设您的 class 具有默认构造函数,因此也充当工厂。如果不是这种情况,可以在附加参数中传递现有实例:
T CreateFromDictionary<T>(IReadOnlyDictionary<string, dynamic> d) where T : new()
{
T obj = new T();
foreach (var propertyInfo in typeof(T).GetProperties())
{
propertyInfo.SetValue(obj, d[propertyInfo.Name]);
}
return obj;
}
调用示例:
Foo myFoo = CreateFromDictionary<Foo>(myDictionary);
如果我必须选择一个,我会选择第一种方法,因为我避免了任何反射,这在运行时很耗时。
您的要求没有明确说明,但我猜您正在寻找一种动态类型,其属性的名称映射到字典键。
在这种情况下,您可以使用像这样的简单字典包装器:
class DynamicDictionaryWrapper : DynamicObject
{
protected readonly Dictionary<string,object> _source;
public DynamicDictionaryWrapper(Dictionary<string,object> source)
{
_source = source;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = null;
return (_source.TryGetValue(binder.Name, out result));
}
}
你可以这样使用:
public static void Main()
{
var myDictionary = new Dictionary<string, dynamic> {
{ "ID1", 12 },
{ "ID2", "Text2"},
{ "ID3", "Text3" }
};
dynamic myObject = new DynamicDictionaryWrapper(myDictionary);
Console.WriteLine(myObject.ID1);
Console.WriteLine(myObject.ID2);
Console.WriteLine(myObject.ID3);
}
输出:
12
Text2
Text3