Передача списка анонимного типа в список динамических объектов - программирование
Подтвердить что ты не робот

Передача списка анонимного типа в список динамических объектов

Почему я не могу добавить List<AnonymousObject> в List<dynamic>? У меня есть следующий код:

var datasource = someList.Select(o => new { x = o.A, y = o.B });
dgvSomeGridView.DataSource = datasource.ToList();
dgvSomeGridView.DataBind();

Затем я обращаюсь к GridView.DataSource со следующим кодом:

var ds = ((List<dynamic>)dgvSomeGridView.DataSource);
....

Но он выдает ошибку в строке, где я отбрасываю ее на List<dynamic>, она говорит:

Невозможно передать объект типа System.Collections.Generic.List'1[<>f__AnonymousType0'8[System.Int32,System.String]] для ввода System.Collections.Generic.List'1[System.Object].

Почему я не могу отнести список анонимного типа к dynamic или как ошибка говорит типу object? Как я могу это решить?

Мой код находится в С#, framework 4.0, в VS2010 Pro, платформа ASP.NET.

Пожалуйста, помогите, спасибо заранее.

4b9b3361

Ответ 1

Так как List<T> не вариант, не ковариант, поэтому вам нужно включить в IEnumerable<dynamic>, который поддерживает со-вариант:

var ds = ((IEnumerable<dynamic>)dgvSomeGridView.DataSource).ToList();

Для более информации о коварианте

Ответ 2

Во-первых, кастинг с общим не работает. Это недействительно:

List<string> source = GetStrings();
List<object> source2 = (List<object>) source;

Причина в том, что список не является ко-вариантом. Если бы это было так, вы могли бы source2.Add(source2);, и вдруг source1 будет содержать себя, когда он должен иметь только строки.

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

В-третьих, переменные dynamic - это способ проверки типа компилятора. Они не проверяют проверку времени выполнения. Вы можете использовать синтаксис С# casting для явного преобразования типа в динамическое... примечание: это не приведение! Вы не можете выполнять кастом выполнения во время, которое не существует во время выполнения.

Однако операции, содержащие выражения типа dynamic, не разрешаются или проверяются типом компилятором. Компилятор объединяет информацию об операции, и эта информация позже используется для оценки операции во время выполнения. В рамках процесса переменные типа dynamic скомпилируются в переменные типа объекта. Поэтому тип dynamic существует только во время компиляции, а не во время выполнения.

static void convertToDynamic()
{
    dynamic d;
    int i = 20;
    d = (dynamic)i;
    Console.WriteLine(d);

    string s = "Example string.";
    d = (dynamic)s;
    Console.WriteLine(d);

    DateTime dt = DateTime.Today;
    d = (dynamic)dt;
    Console.WriteLine(d);

}
// Results: 
// 20 
// Example string. 
// 2/17/2009 9:12:00 AM

Наконец, если вы все еще хотите List<dynamic>, сделайте следующее:

var anonList = GetAnonList();
List<dynamic> dynamicList = anonList.Select(x => (dynamic)x).ToList();

Но вы могли бы так же легко сделать это:

var anonList = GetAnonList();
List<object> objectList = anonList.Cast<object>().ToList();