2011-07-06 24 views
22

¿Cómo puedo crear un nuevo List<T> donde el T es un tipo de objeto dinámico .Cómo crear una lista con un tipo de objeto dinámico

que tienen

dynamic DyObj = new ExpandoObject(); 

if (condition1) 
{ 
    DyObj.Required = true; 
    DyObj.Message = "This is the first property being accessed through dynamic object"; 
} 
if (condition2) 
{ 
    DyObj.Required = false; 
    DyObj.Message = "This is the second property...."; 
} 
// and so on... 

que quieren crear List<Dyobj> y asignar todos los mensajes a Dyobj sobre la base de condiciones.

datos de seguimiento de:

var DyObjectsList = new List<dynamic>; 
dynamic DyObj = new ExpandoObject(); 
if (condition1) { 
    DyObj.Required = true; 
    DyObj.Message = "Message 1"; 
    DyObjectsList.Add(DyObj); 
} 
if (condition2) { 
    DyObj.Required = false; 
    DyObj.Message = "Message 2"; 
    DyObjectsList.Add(DyObj); 
} 

curiosamente todos los objetos en DyObjectsList se sustituyen con los valores del último objeto asignado.

Respuesta

41

Sólo tiene que utilizar dynamic como argumento:

var list = new List<dynamic>(); 
+0

@Krik gracias. Aquí esta lo que hice. var DyObjectsList = new List ; DyObj dinámico = nuevo ExpandoObject(); if (condition1) {DyObj.Required = true; DyObj.Message = "Mensaje 1"; DyObjectsList .Add (DyObj); } if (condition2) {DyObj.Required = false; DyObj.Message = "Mensaje 2"; DyObjectsList .Add (DyObj); } Curiosamente, todos los objetos en DyObjectsList se reemplazan por los valores del último objeto asignado. – BumbleBee

+3

@BumbleBee, esto se debe a que está sobrescribiendo los valores de su objeto. Instancias ** una ** instancia de tu 'DyObj' y procedes a asignar valores * a esa misma instancia * dos veces.Debería mover la línea 'dynamic DyObj = new ExpandoObject();' dentro de sus bloques if, y debería terminar con dos copias de esa línea, ya que quiere agregar dos instancias separadas. –

4

Parece que podría ser un poco confundido en cuanto a cómo funciona el método .Add. Me referiré directamente a tu código en mi explicación.

Básicamente en C#, el método .Add de una lista de objetos no copia los nuevos objetos añadidos a la lista, simplemente copia una referencia al objeto (que es la dirección) en la lista. Entonces, el motivo por el que todos los valores de la lista apuntan al mismo valor se debe a que solo ha creado 1 nuevo DyObj. Entonces su lista esencialmente se ve así.

DyObjectsList[0] = &DyObj; // pointing to DyObj 
DyObjectsList[1] = &DyObj; // pointing to the same DyObj 
DyObjectsList[2] = &DyObj; // pointing to the same DyObj 

...

La manera más fácil de arreglar su código es crear un nuevo DyObj para cada .Add. Poner el nuevo dentro del bloque con el .Add lograría este objetivo en esta instancia particular.

var DyObjectsList = new List<dynamic>; 
if (condition1) { 
    dynamic DyObj = new ExpandoObject(); 
    DyObj.Required = true; 
    DyObj.Message = "Message 1"; 
    DyObjectsList .Add(DyObj); 
} 
if (condition2) { 
    dynamic DyObj = new ExpandoObject(); 
    DyObj.Required = false; 
    DyObj.Message = "Message 2"; 
    DyObjectsList .Add(DyObj); 
} 

su lista resultante esencialmente se parece a esto

DyObjectsList[0] = &DyObj0; // pointing to a DyObj 
DyObjectsList[1] = &DyObj1; // pointing to a different DyObj 
DyObjectsList[2] = &DyObj2; // pointing to another DyObj 

Ahora en algunos otros idiomas este enfoque no funcionaría, ya que al salir del bloque, los objetos declarados en el ámbito del bloque podría salir del alcance y ser destruido. Por lo tanto, se quedaría con una colección de punteros que apuntan a la basura.

Sin embargo, en C#, si existe una referencia al nuevo DyObjs cuando abandona el bloque (y existen en su Lista debido a la operación .Add) entonces C# no libera la memoria asociada con ese puntero. Por lo tanto, los Objetos que creó en ese bloque persisten y su Lista contiene punteros a objetos válidos y su código funciona.

Cuestiones relacionadas