【问题标题】:How to create a class from a Dictionary in C#? [duplicate]如何从 C# 中的字典创建一个类? [复制]
【发布时间】:2019-06-16 23:55:21
【问题描述】:

我编写了一个创建字典的方法。我需要把这个字典转换成一个类。

字典示例

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

【问题讨论】:

  • 看起来你已经创建了这个类。你的问题是什么?您不知道如何从字典中检索值,不知道如何将值分配给对象的属性,还是什么?
  • @JohnWu 这些只是示例。 Sample 字典是在运行时创建的(我不知道它们的键/类型)。在运行时,我需要从该字典创建一个类。
  • 当你说“创建一个类”时,你的意思是“创建这个类的一个实例并填充它的属性”还是实际创建一个具有这些属性的类型?如果是后者,那么一旦它被创建,你将如何在你的程序中使用它?
  • 程序能够在运行时创建类是一个非常不寻常的要求。奇怪的是,事实上。类(和一般类型)的要点是它们在编译时使用以确保您的程序结构正确。也许你有一个xy problem
  • 不,我实际上是指类本身。是否可以在运行时将字典键转换为类成员?

标签: c# dynamic-class-creation


【解决方案1】:

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

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

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

Link to working example on DotNetFiddle

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 2016-11-10
      • 2019-03-15
      • 2021-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      • 2011-08-17
      相关资源
      最近更新 更多