0

我写了一个创建字典的方法。我需要将此字典转换为一个类。

字典示例

 Dictionary<string, dynamic> myDictionary = new Dictionary<string, dynamic> {
            { "ID1", 12 },
            { "ID2", "Text2"},
            { "ID3", "Text3" }
        };

这是需要创建的类的示例:

public class Foo
    {
        public int ID1 { get; set; }
        public string ID2 { get; set; }
        public string ID3 { get; set; }
    }
4

2 回答 2

3

正如其他人提到的那样,这种情况很常见,并且肯定需要从更好的角度解决它的上下文,因为我怀疑代码库的架构不好。尽管如此,您的问题仍然有效。要解决它,您至少有两种可能性:

1.需要开发时间;运行时可忽略不计的时间- 只需创建一个函数,将给定字典映射到您的类的实例。例子:

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.需要运行时间;可忽略的开发时间- 创建一个将给定字典映射到任意类的函数,通常使用反射。下面的示例假定您的类具有默认构造函数,因此也充当工厂。如果不是这种情况,则可以在附加参数中传递现有实例:

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);

如果我必须选择一个,我会选择第一种方法,因为我避免了任何反射,这在运行时很耗时。

于 2019-06-17T00:16:33.713 回答
3

您的要求没有明确说明,但我猜您正在寻找具有名称映射到字典键的属性的动态类型。

在这种情况下,您可以使用像这样的简单字典包装器:

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

链接到 DotNetFiddle 上的工作示例

于 2019-06-17T00:18:54.463 回答