【问题标题】:Creating classes dynamically with name of class使用类名动态创建类
【发布时间】:2018-05-16 19:25:10
【问题描述】:

我想做类似的事情: 类+字段的用户输入名称。 代码查找是否曾经声明过具有该名称的类。 代码使用字段创建类。

我知道我可以用许多 switch case 来做到这一点,但我可以根据用户输入在某种程度上自动执行此操作吗? 用户输入的名称将是类名称。 我在 C# 中执行此操作。

【问题讨论】:

  • 为什么用户永远需要知道类的名称或组成?如果他们有这样的知识水平,为什么还需要程序员?
  • 仅作为示例。实际上,我正在从源获取数据,但试图将其序列化为一堆不同的类。从技术上讲,我的代码是创建类的“用户”。
  • 按名称创建类是 SO 上比较常见的问题之一,您应该能够找到答案。我不明白的是“+字段”部分。什么意思?
  • 字段只是类中的属性。感谢您的提醒,我认为 Activator.CreateInstance 将是我正在寻找的?
  • 如果我理解正确,那么是的Activator.CreateInstance()。但是字段不同于属性,请注意您的术语。

标签: c# class dynamic automation


【解决方案1】:

System.Reflection.Emit 命名空间可以为您提供在运行时创建动态类所需的工具。但是,如果您以前从未使用过它,那么您尝试完成的任务可能会变得非常困难。当然,预制代码会有很大帮助,我认为在这里你可以找到很多。

但我建议你另辟蹊径。也许没有那么灵活,但肯定很有趣。涉及到DynamicObject类的使用:

public class DynamicClass : DynamicObject
{
    private Dictionary<String, KeyValuePair<Type, Object>> m_Fields;

    public DynamicClass(List<Field> fields)
    {
        m_Fields = new Dictionary<String, KeyValuePair<Type, Object>>();

        fields.ForEach(x => m_Fields.Add
        (
            x.FieldName,
            new KeyValuePair<Type, Object>(x.FieldType, null)
        ));
    }

    public override Boolean TryGetMember(GetMemberBinder binder, out Object result)
    {
        if (m_Fields.ContainsKey(binder.Name))
        {
            result = m_Fields[binder.Name].Value;
            return true;
        }

        result = null;
        return false;
    }

    public override Boolean TrySetMember(SetMemberBinder binder, Object value)
    {
        if (m_Fields.ContainsKey(binder.Name))
        {
            Type type = m_Fields[binder.Name].Key;

            if (value.GetType() == type)
            {
                m_Fields[binder.Name] = new KeyValuePair<Type, Object>(type, value);
                return true;
            }
        }

        return false;
    }
}

使用示例(请记住,Field 是一个小而简单的类,具有两个属性,Type FieldTypeString FieldName,您必须自己实现):

List<Field>() fields = new List<Field>()
{ 
    new Field("ID", typeof(Int32)),
    new Field("Name", typeof(String))
};

dynamic myObj = new DynamicClass(fields);

myObj.ID = 10;
myObj.Name= "A";

Console.WriteLine(myObj.ID.ToString() + ") " + myObj.Name);

【讨论】:

  • 嗯,感谢您的洞察力。我可以使用反射来获取类的属性。由于程序的主要目的是使它们成为预定义的 Xml Serializable 类,但我认为我不能使用动态。
  • 这有点棘手,但它是可行的。在此处阅读接受的答案:stackoverflow.com/questions/7501846/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 2013-05-05
  • 2014-04-24
  • 2015-06-29
  • 1970-01-01
  • 2016-03-01
相关资源
最近更新 更多