Como criar próprio tipo dinâmico ou objeto dinâmico em C #?

130

Existe, por exemplo, a propriedade ViewBag da ControllerBaseclasse e podemos obter / definir valores dinamicamente e adicionar qualquer número de campos ou propriedades adicionais a esse objeto, o que é legal. Quero usar algo assim, além do aplicativo MVC e da Controllerclasse em outros tipos de aplicações. Quando tentei criar um objeto dinâmico e definir sua propriedade, como abaixo:

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

Eu recebi RuntimeBinderExceptiona mensagem Property ou indexer '<> f__AnonymousType0.A' não pode ser atribuído a - ele é lido apenas na linha 2. Também sugiro que não é exatamente o que estou procurando. Talvez haja alguma classe que possa me permitir fazer algo como:

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

com propriedades dinâmicas de adição e configuração.

Dmytro
fonte

Respostas:

279
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());

Leia mais sobre a classe ExpandoObject e para obter mais exemplos: representa um objeto cujos membros podem ser adicionados e removidos dinamicamente em tempo de execução.

Mario Sannum
fonte
3
Por favor vote neste recurso no Visual Studio UserVoice .
orad 6/02/15
33

Recentemente, tive a necessidade de dar um passo adiante, que era fazer com que as adições de propriedades no objeto dinâmico fossem dinâmicas, com base nas entradas definidas pelo usuário. Os exemplos aqui, e da documentação do ExpandoObject da Microsoft , não abordam especificamente a adição dinâmica de propriedades, mas podem ser deduzidos de como você enumera e exclui propriedades. De qualquer forma, achei que isso poderia ser útil para alguém. Aqui está uma versão extremamente simplificada de como adicionar propriedades verdadeiramente dinâmicas a um ExpandoObject (ignorando palavras-chave e outras formas de manipulação):

        // 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
fonte
32

ExpandoObject é o que você está procurando.

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;
não mostrar
fonte
11

Você pode usar o ExpandoObject Classque está no System.Dynamicespaço para nome.

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

Mais informações podem ser encontradas no ExpandoObject MSDN

Kishore Kumar
fonte
9
dynamic myDynamic = new { PropertyOne = true, PropertyTwo = false};
smedasn
fonte
7
dynamic MyDynamic = new ExpandoObject();
Davecz
fonte
7
 var data = new { studentId = 1, StudentName = "abc" };  

Ou o valor está presente

  var data = new { studentId, StudentName };
Rocha
fonte