Создание динамического класса в C # - PullRequest
5 голосов
/ 23 апреля 2010

Возможно ли во время выполнения создать класс из DataTable, где ColumnName будет свойствами динамического класса?

Ответы [ 5 ]

4 голосов
/ 23 апреля 2010

С помощью 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

Не рекомендовать его или что-то еще, но он показывает вам, что это возможно.

1 голос
/ 23 апреля 2010

Читая ваши комментарии, я не понял вашего значения.Просто используйте Generics: используйте поля List для генерации объектов.Код довольно прост:

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);
        }        
    }
1 голос
/ 23 апреля 2010

Если у вас есть C # 4, вы можете использовать новую функцию динамики и ExpandoObject.Вы можете прочитать об этом здесь .

1 голос
/ 23 апреля 2010

Да (с использованием Reflection.Emit), но это плохая идея.
Что ты пытаешься сделать?

0 голосов
/ 18 ноября 2011

Я собираюсь изучить упомянутый 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 не работает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...