Dynamic class creation in C#

2019-02-17 18:24发布

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

标签: c# class dynamic
5条回答
Bombasti
2楼-- · 2019-02-17 18:45

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.

查看更多
仙女界的扛把子
3楼-- · 2019-02-17 18:47

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);
        }        
    }
查看更多
Emotional °昔
4楼-- · 2019-02-17 18:52

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

查看更多
Summer. ? 凉城
5楼-- · 2019-02-17 18:55

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.

查看更多
小情绪 Triste *
6楼-- · 2019-02-17 19:03

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.

查看更多
登录 后发表回答