LinQ包含Cast方法,该方法将列表中的每个条目转换为键入T。假设我们有一个列表,如下所示:
List<Object> obj = new List<Object>();
obj.Add("A");
obj.Add("B");一个有工作的演员
var list = obj.Cast<string>();我想做的事
Type t = typeof(String);
Object list = obj.Cast(t);一个解决方案是使用反射并一般性地创建一个列表并填充它,但是我想知道是否有更好的解决方案?听说.NET 4.0应该支持一些协方差,这可能是一种方法。
额外信息与反射解决
我得到的错误是下面的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,但不能抛出,因为它是列表的泛型类型。
我构建了以下解决方案-我将像没有反射的东西一样:
public static object Cast(this IEnumerable list, Type type)
{
var newList = Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
foreach (var item in list)
newList.GetType().GetMethod("Add").Invoke(newList, new object[] { item });
return newList;
}发布于 2010-08-10 13:39:12
静态地这样做是不可能的,就像您可以用一个对象来完成它一样。
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();
}发布于 2010-08-10 14:19:10
我不太明白为什么要这样做,但您可以通过反射调用Enumerable.Cast<T>:
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 });在这种情况下,运行时类型的stringSequence将实现IEnumerable<string>。
发布于 2010-08-10 13:27:01
您不需要对只在运行时才知道的类型进行强制转换。对象的类型不会改变,因为您将执行强制转换,如果它是字符串,那么稍后它将是一个字符串,如果您将它赋值给string或object变量,这并不重要。
在对反射方法进行操作时,不需要考虑转换为真实的对象类型。它可以保留为一个对象变量,因为在使用反射时,您可以访问所有它的真实类型成员,而无需任何强制转换。
https://stackoverflow.com/questions/3449349
复制相似问题