Linq Cast<T> with System.Type
LinQ contains the method Cast which casts each entry in the list to type T. Lets say we have a list which looks like the following:
List<Object> obj = new List<Object>();
obj.Add("A");
obj.Add("B");
A working cast could be
var list = obj.Cast<string>();
What I would like to work
Type t = typeof(String);
Object list = obj.Cast(t);
A solution would be to use reflection and genericly cre开发者_StackOverflow社区ate a list and populate it but I was wondering if there exist any better solution? Heard that .NET 4.0 should support some co/contra-variance which may be a way to do it.
Extra Information and Reflection Soulution
The error I get is the following 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]
.
Note that CrashEntry implements IStaticEntry but cannot be casted because it is a generic type of the list.
I constructed the following solution through I would stille like something without Reflection:
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;
}
I don't quite understand why you'd want to do this but you could invoke Enumerable.Cast<T>
through reflection:
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 });
In which case the runtime type of stringSequence
would implement IEnumerable<string>
.
It's not possible to do this statically, any more than you can do it with a single object.
Type t = typeof(string);
var x = (t)obj; // invalid
However, it is possible to treat the elements dynamically so that a cast to the underlying type isn't necessary:
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();
}
You do not need to cast something on the type that you will know only in runtime. The type of the object will not change because you will perform cast, if it was string it will be a string later and it do not matter if you will assign it to string or object variable.
You do not need to care about casting to a real object type while you are operating on reflection methods. It can stay as an object variable because while using reflection you can access all of it's real type members anyway without any cast.
精彩评论