Dynamic class creation in C#

前端 未结 5 745
离开以前
离开以前 2021-01-13 10:07

Is it possible in runtime to create a class from DataTable where ColumnName will be dynamic-class properties?

相关标签:
5条回答
  • 2021-01-13 10:27

    I am going to be looking into the ExpandoObject that was mentioned (I voted for that solution by the way as it seems easier) but yes, it is possible. I'm building a class in one of my projects where a third party utility requires a CSV line to be defined as a class.

    You can build the code (I included \r\n so that I could read the resultant code):

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

    ... Like I mentioned, If I had to do it over again I would investigate the ExpandoObject but it is definitely possible to create a class from a DataTable. You would need to interrogate the column names to build your fields; my example had the list of column names provided from a "," delimited string.

    My example is from a very specific use case but it should be enough to get you going should the ExpandoObject not work for you.

    0 讨论(0)
  • 2021-01-13 10:29

    If you have C# 4 you can make use of the new dynamics feature and the ExpandoObject. You can read a tutorial about it here.

    0 讨论(0)
  • 2021-01-13 10:39

    Yes (using Reflection.Emit), but it's a bad idea.
    What are you trying to do?

    0 讨论(0)
  • 2021-01-13 10:41

    Reading your comments, I undestood your mean. Just use Generics: using List fields to generate the objects. The code is quite simple:

    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);
            }        
        }
    
    0 讨论(0)
  • 2021-01-13 10:51

    With C# 4, you can do this

    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
    

    Not recommending it or anything, but it shows you it is possible.

    0 讨论(0)
提交回复
热议问题