【问题标题】:Dynamic class creation in C#C# 中的动态类创建
【发布时间】:2011-02-11 12:29:25
【问题描述】:

是否可以在运行时从 DataTable 创建一个类,其中 ColumnName 将是动态类属性?

【问题讨论】:

  • 为什么?你想做什么?
  • 你的意思是定义一个新的类,还是动态设置一个现有的类属性?
  • 我想用 dataTable 列名创建新类
  • 为什么不能在设计时创建类?
  • 我刚刚在我的帖子中添加了代码。如果您已经看到了,请对评论表示抱歉

标签: c# class dynamic


【解决方案1】:

使用 C# 4,您可以做到这一点

dynamic foo = new ExpandoObject();

// mimic grabbing a column name at runtime and adding it as a property
((IDictionary<string, object>)foo).Add("Name", "Apple");

Console.WriteLine(foo.Name); // writes Apple to screen

不推荐它或任何东西,但它告诉你这是可能的。

【讨论】:

    【解决方案2】:

    是的(使用 Reflection.Emit),但这是个坏主意。
    你想做什么?

    【讨论】:

    • 我有 RadGridView,当我使用 dataTable 作为他的源时,它会出现一些问题。但是当我使用 List 时,一切正常。有什么想法吗?
    • 你应该把它作为一个单独的问题来问。
    【解决方案3】:

    如果您有 C# 4,则可以使用新的动态特性和 ExpandoObject。你可以read a tutorial about it here

    【讨论】:

    • 使用这项技术真的令人难以置信!
    【解决方案4】:

    读了你的 cmets,我明白你的意思。 只需使用泛型:使用列表字段来生成对象。 代码很简单:

    public class DynClass<T, P>
        {
            public DynClass()
            {
                _fields = new Dictionary<T, P>();
            }
    
            private IDictionary<T, P> _fields;
    
            public IDictionary<T, P> Fields
            {
                get { return _fields; }
            }
    
        }
    
        public class TestGenericInstances
        {
            public TestGenericInstances()
            {
                Client cli = new Client("Ash", "99999999901");
    
                /* Here you can create any instances of the Class. 
                 * Also DynClass<string, object>
                 * */
                DynClass<string, Client> gen = new DynClass<string, Client>();
    
                /* Add the fields
                 * */
                gen.Fields.Add("clientName", cli);
    
                /* Add the objects to the List
                 * */
                List<object> lstDyn = new List<object>().Add(gen);
            }        
        }
    

    【讨论】:

    • 每次我可以有不同名称和类型的不同列。你能详细告诉我你的变种还是给我看看代码?
    【解决方案5】:

    我将研究提到的 ExpandoObject(顺便说一下,我投票支持该解决方案,因为它看起来更容易)但是是的,这是可能的。我正在我的一个项目中构建一个类,其中第三方实用程序需要将 CSV 行定义为一个类。

    您可以构建代码(我包含了 \r\n 以便我可以阅读生成的代码):

            string code = "using FileHelpers;\r\n\r\n";
    
            code += "[DelimitedRecord(\"" + delimiter + "\")]\r\n";
            code += "public class CustomCSVInputFile ";
            code += "{ \r\n";
    
            foreach (string column in columnList)
            {
              code += "   public string " + column.Replace(" ", "") + ";\r\n";
            }
            code += "}\r\n";
    
            CompilerResults compilerResults = CompileScript(code);
    

    ...

        public static CompilerResults CompileScript(string source)
        {
            CompilerParameters parms = new CompilerParameters();
            FileHelperEngine engine;
    
            parms.GenerateExecutable = false;
            parms.GenerateInMemory = true;
            parms.IncludeDebugInformation = false;
    
            string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\\", "").Trim();
    
            parms.ReferencedAssemblies.Add(Path.Combine(path, "FileHelpers.dll"));
    
            CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp");
    
            return compiler.CompileAssemblyFromSource(parms, source);
        } 
    

    ... 就像我提到的,如果我必须重新做一遍,我会调查 ExpandoObject,但绝对可以从 DataTable 创建一个类。您需要询问列名来构建您的字段;我的示例具有从“,”分隔的字符串提供的列名列表。

    我的示例来自一个非常具体的用例,但如果 ExpandoObject 不适合您,它应该足以让您继续前进。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-23
      • 2015-12-31
      • 2013-04-09
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 2018-05-25
      相关资源
      最近更新 更多