¿Cómo crear un tipo dinámico propio o un objeto dinámico en C #?

130

Existe, por ejemplo, la propiedad ViewBag de la ControllerBaseclase y podemos obtener / establecer dinámicamente valores y agregar cualquier número de campos o propiedades adicionales a este objeto, lo cual es genial. Quiero usar algo así, más allá de la aplicación MVC y la Controllerclase en otro tipos de aplicaciones. Cuando intenté crear un objeto dinámico y establecer su propiedad como a continuación:

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

Tengo el RuntimeBinderExceptionmensaje Propiedad o indexador '<> f__AnonymousType0.A' no se puede asignar, se lee solo en la línea 2. También sugiero que no es exactamente lo que estoy buscando. Tal vez hay alguna clase que me permita hacer algo como:

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

con propiedades dinámicas de adición y configuración.

Dmytro
fuente

Respuestas:

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

Lea más sobre la clase ExpandoObject y para obtener más muestras: representa un objeto cuyos miembros se pueden agregar y quitar dinámicamente en tiempo de ejecución.

Mario Sannum
fuente
3
Vote por esta característica en Visual Studio UserVoice .
orad
33

Recientemente tuve la necesidad de llevar esto un paso más allá, que era hacer que las adiciones de propiedades en el objeto dinámico, dinámicas mismas, se basaran en entradas definidas por el usuario. Los ejemplos aquí, y de la documentación de ExpandoObject de Microsoft , no abordan específicamente la adición dinámica de propiedades, pero pueden deducirse de cómo enumera y elimina propiedades. De todos modos, pensé que esto podría ser útil para alguien. Aquí hay una versión extremadamente simplificada de cómo agregar propiedades verdaderamente dinámicas a un ExpandoObject (ignorando las palabras clave y otros manejos):

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

ExpandoObject es lo que buscas

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;
nada
fuente
11

Puede usar ExpandoObject Classcuál está en el System.Dynamicespacio de nombres.

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

Se puede encontrar más información en ExpandoObject MSDN

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

O el valor está presente

  var data = new { studentId, StudentName };
Rock
fuente