Linq Cast <T> с System.Type

LinQ содержит метод В ролях, который бросает каждую запись в списке, чтобы ввести T. Допустим, у нас есть список, который выглядит следующим образом:

List<object> obj = new List<object>();
obj.Add("A");
obj.Add("B");
<p>Рабочий состав может быть</p>
<pre class="prettyprint linenums"><code>var list = obj.Cast&lt;string&gt;();
&lt;/string&gt;</code>

Что я хотел бы работать

<code>Type t = typeof(String);
Object list = obj.Cast(t);</code>

Решение будет состоять в том, чтобы использовать отражение и создать общий список и заполнить его, но мне было интересно, есть ли лучшее решение? Слышал, что .NET 4.0 должен поддерживать некоторую co/contra-дисперсию, которая может быть способом сделать это.

Дополнительная информация и рефлексия Soulution

Ошибка, которую я получаю, следующая The model item passed into the dictionary is of type System.Collections.Generic.List1[IStatisticEntry], but this dictionary requires a model item of type System.Collections.Generic.List1[CrashStatistic+CrashEntry]. Обратите внимание: CrashEntry реализует IStaticEntry, но не может быть запущен, потому что это общий тип списка.

Я построил следующее решение, через которое я мог бы выглядеть как-то без Reflection:

<code>public static object Cast(this IEnumerable list, Type type) { var newList = Activator.CreateInstance(typeof(List&lt;&gt;).MakeGenericType(type)); foreach (var item in list) newList.GetType().GetMethod("Add").Invoke(newList, new object[] { item }); return newList; }</code>
3 ответа

Это невозможно сделать статически, не больше, чем вы можете сделать с помощью одного объекта.

Type t = typeof(string);
var x = (t)obj; // invalid

Однако можно динамически обрабатывать элементы так, чтобы приведение к базовому типу не требовалось:

static void Main(string[] args)
{ List<object> obj = new List<object>(); obj.Add("A"); obj.Add("B"); var list = obj.Cast<dynamic>(); foreach (var item in list) { Console.WriteLine(item[0]); } Console.ReadKey();
}
</dynamic></object></object>


Я не совсем понимаю, почему вы хотите это сделать, но вы можете вызвать Enumerable.Cast через отражение:

List<object> objectList = new List<object> { "Foo", "Bar" };
object stringSequence = typeof(Enumerable) .GetMethod("Cast", BindingFlags.Public | BindingFlags.Static) .MakeGenericMethod(typeof(string)) .Invoke(null, new[] { objectList });
<p>В этом случае тип выполнения <code>stringSequence</code> будет реализовывать <code>IEnumerable</code>.</p></object></object>


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

Вам не нужно заботиться о литье к реальному типу объекта во время работы с методами отражения. Он может оставаться как переменная объекта, потому что при использовании отражения вы можете получить доступ ко всем его действительным членам типа в любом случае без какого-либо приведения.

licensed under cc by-sa 3.0 with attribution.