Как создать собственный динамический тип или динамический объект на C #?

132

Вот, например, свойство класса ViewBag,ControllerBase и мы можем динамически получать / устанавливать значения и добавлять любое количество дополнительных полей или свойств к этому объекту, что круто. Я хочу использовать что-то подобное, помимо приложения и Controllerкласса MVC в других типы приложений. Когда я попытался создать динамический объект и установить его свойство, как показано ниже:

1. dynamic MyDynamic = new { A="a" };
2. MyDynamic.A = "asd";
3. Console.WriteLine(MyDynamic.A);

У меня есть RuntimeBinderExceptionсообщение. Свойство или индексатор '<> f__AnonymousType0.A' не может быть назначен - он читается только в строке 2. Также я предлагаю, что это не совсем то, что я ищу. Может быть, есть какой-то класс, который позволяет мне делать что-то вроде:

??? MyDynamic = new ???();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = DateTime.Now;
MyDynamic.TheAnswerToLifeTheUniverseAndEverything = 42;

с динамическим добавлением и настройкой свойств.

Дмитро
источник

Ответы:

281
dynamic MyDynamic = new System.Dynamic.ExpandoObject();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.Number = 12;
MyDynamic.MyMethod = new Func<int>(() => 
{ 
    return 55; 
});
Console.WriteLine(MyDynamic.MyMethod());

Дополнительные сведения о классе ExpandoObject и другие примеры: представляет объект, члены которого могут быть динамически добавлены и удалены во время выполнения.

Марио Саннум
источник
3
Проголосуйте за эту функцию в Visual Studio UserVoice .
orad
33

Недавно у меня возникла необходимость сделать еще один шаг вперед, который заключался в том, чтобы сделать добавления свойств в динамическом объекте динамическими сами по себе на основе определенных пользователем записей. В приведенных здесь примерах и в документации Microsoft ExpandoObject не говорится о динамическом добавлении свойств, но можно предположить, исходя из того, как вы перечисляете и удаляете свойства. Во всяком случае, я подумал, что это может быть кому-то полезно. Вот чрезвычайно упрощенная версия того, как добавить действительно динамические свойства в ExpandoObject (без учета ключевых слов и другой обработки):

        // my pretend dataset
        List<string> fields = new List<string>();
        // my 'columns'
        fields.Add("this_thing");
        fields.Add("that_thing");
        fields.Add("the_other");

        dynamic exo = new System.Dynamic.ExpandoObject();

        foreach (string field in fields)
        {
            ((IDictionary<String, Object>)exo).Add(field, field + "_data");
        }

        // output - from Json.Net NuGet package
        textBox1.Text = Newtonsoft.Json.JsonConvert.SerializeObject(exo);
AlienFromCA
источник
32

ExpandoObject это то, что вы ищете.

dynamic MyDynamic = new ExpandoObject(); // note, the type MUST be dynamic to use dynamic invoking.
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.TheAnswerToLifeTheUniverseAndEverything = 42;
nothrow
источник
11

Вы можете использовать то, ExpandoObject Classчто находится в System.Dynamicпространстве имен.

dynamic MyDynamic = new ExpandoObject();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = "C";
MyDynamic.SomeProperty = SomeValue
MyDynamic.number = 10;
MyDynamic.Increment = (Action)(() => { MyDynamic.number++; });

Более подробную информацию можно найти на ExpandoObject MSDN

Кишор Кумар
источник
9
dynamic myDynamic = new { PropertyOne = true, PropertyTwo = false};
smedasn
источник
7
 var data = new { studentId = 1, StudentName = "abc" };  

Или значение присутствует

  var data = new { studentId, StudentName };
рок
источник