开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜