Подтвердить что ты не робот

Как создать список с типом динамического объекта

Как создать новый List<T>, где T - это динамический объект Type.

У меня

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

Я хочу создать List<Dyobj> и назначить все сообщения Dyobj на основе условий.

Последующие данные из комментариев:

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

интересно, что все объекты в DyObjectsList заменяются значениями последнего назначенного объекта.

4b9b3361

Ответ 1

Просто используйте dynamic в качестве аргумента:

var list = new List<dynamic>();

Ответ 2

Похоже, вы можете быть немного смущены тем, как работает метод .Add. Я буду ссылаться непосредственно на ваш код в своем объяснении.

В основном в С# метод .Add из списка объектов не копирует новые добавленные объекты в список, он просто копирует ссылку на объект (его адрес) в список. Поэтому причина, по которой каждое значение в списке указывает на одно и то же значение, состоит в том, что вы создали только 1 новый DyObj. Поэтому ваш список выглядит примерно так.

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

...

Самый простой способ исправить ваш код - создать новый DyObj для каждого .Add. Ввод нового внутри блока с помощью .Add достигнет этой цели в данном конкретном случае.

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

ваш результирующий список по существу выглядит следующим образом

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

Теперь на некоторых других языках этот подход не будет работать, потому что, когда вы покидаете блок, объекты, объявленные в области блока, могут выйти из области действия и быть уничтожены. Таким образом, вы останетесь с набором указателей, указывая на мусор.

Однако в С#, если ссылка на новый DyObjs существует, когда вы покидаете блок (и они существуют в вашем списке из-за операции .Add), то С# не освобождает память, связанную с этим указателем. Поэтому объекты, созданные вами в этом блоке, сохраняются, и ваш список содержит указатели на действительные объекты и ваш код работает.