2011-07-06 17 views
22

Jak mogę utworzyć nowy List<T> gdzie T jest dynamiczny Rodzaj obiektu.Jak utworzyć listę z dynamicznym typu obiektu

mam

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... 

Chcę utworzyć List<Dyobj> i przypisać wszystkie komunikaty Dyobj oparte na warunkach.

Kontynuacja dane z komentarzy:

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

ciekawe wszystkie obiekty w DyObjectsList są zastępowane wartościami ostatniego przydzielonego obiektu.

Odpowiedz

41

Wystarczy użyć dynamic jako argument: Wydaje

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

@Krik dziękuję. Oto co zrobiłem. var DyObjectsList = nowa lista ; 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); } co ciekawe wszystkie obiekty w obiekcie DyObjectsList są zastępowane wartościami ostatniego przypisanego obiektu. – BumbleBee

+3

@BumbleBee, to dlatego, że nadpisujesz wartości swojego obiektu. Tworzysz ** jedną ** instancję swojego 'DyObj' i kontynuujesz przypisywanie wartości do * tej samej instancji * dwukrotnie.Powinieneś przenieść linię 'dynamic DyObj = new ExpandoObject();' wewnątrz twoich bloków if, a powinieneś skończyć z dwiema kopiami tej linii, ponieważ chcesz dodać dwie oddzielne instancje. –

4

może być nieco zdezorientowany, jak działa metoda .Add. Odnoszę się bezpośrednio do twojego kodu w moim wyjaśnieniu.

Zasadniczo w języku C# metoda .Add dla listy obiektów nie kopiuje nowych dodanych obiektów do listy, a jedynie kopiuje odniesienie do obiektu (jego adresu) do listy. Więc powodem, dla którego każda wartość na liście wskazuje na tę samą wartość, jest to, że utworzyłeś tylko 1 nowy DyObj. Twoja lista zasadniczo wygląda tak.

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

...

Najprostszym sposobem, aby naprawić swój kod jest stworzenie nowego DyObj dla każdego .Add. Umieszczenie nowego wewnątrz bloku za pomocą .Add może osiągnąć ten cel w tym konkretnym przypadku.

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

Twój wynikające Lista zasadzie wygląda to

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

obecnie w niektórych innych językach podejście to nie będzie działać, ponieważ po wyjściu z bloku, obiekty zadeklarowane w ramach bloku mógł wykraczać poza zakres i być zniszczonym. W ten sposób pozostałbyś ze zbiorem wskaźników wskazujących na śmieci.

Jednak w języku C#, jeśli odniesienie do nowego DyObjs istnieje po opuszczeniu bloku (i istnieją one na liście z powodu operacji .Add), to C# nie zwalnia pamięci skojarzonej z tym wskaźnikiem. W związku z tym Obiekty utworzone w tym bloku będą się utrzymywać, a Twoja Lista zawiera wskaźniki do prawidłowych obiektów, a Twój kod działa.

Powiązane problemy