2016-08-22 23 views
6
static IEnumerable<U> DoSomething<T, U>(IEnumerable<T> a) 
    where T : U 
{ 
    // Works, compiler can compile-time statically cast 
    // T as U. 
    T testA = default(T); 
    U testB = testA; 

    // And the following works, though: 
    IEnumerable<string> test2A = null; 
    IEnumerable<object> test2B = test2A; 

    // Doesn’t work. Compiler cannot compile-time statically 
    // cast IEnumerable<T> to IEnumerable<U> even though it is 
    // out and T is U. 
    return a; 
} 

我有代码在哪里能够执行这种类型的隐式转换将节省我写了很多样板接口实现代码。 这似乎是协方差本应帮助的事情。 但我总是得到这个错误在return a;线之上:为什么协变隐式转换忽略通用约束?

错误CS0266:无法键入“System.Collections.Generic.IEnumerable <牛逼>”隐式转换为“System.Collections.Generic.IEnumerable <ü> ”。一个显式转换存在(是否缺少强制转换?)

这是为什么这样,是有办法解决这个没有做这样的事情return from o in a select o;

回答

6

当我最小的摄制乱搞和读取类似,但无关,问题about interface casting,我意识到,下面编译:

static IEnumerable<U> DoSomethingElse<T, U>(IEnumerable<T> a) 
    where T : class, U 
{ 
    // Works! Ridik! 
    return a; 
} 

而且还下列失败,出现相同的错误消息:

static void Blah() 
{ 
    // Fails for I bet the same reason that DoSomething{T, U} fails: 
    IEnumerable<int> a = null; 
    IEnumerable<object> b = a; 
} 

错误CS0266:无法隐式转换类型 'System.Collections.Generic.IEnumerable <INT>' 到“System.Collections.Generic .IEnumeume <object>'。一个显式转换存在(是否缺少强制转换?)

因此,这似乎与.NET如何限制某些类型的任务的引用类型,因为拳击在这些情况下,要么是错误的东西(例如,你可能会假定引用类型,并且实际上正在处理一个值类型的副本),或者很难/不可能在运行时实现(给定一个IEnumerable<int>,你必须实现一个包装适配类,OK,这听起来像是某种东西。 net不能/不应该在运行时为你做)。我认为它是.net允许指针式多态的情况,它本质上与价值类型的概念不相容。

因此,对于我的情况,我不需要在我的API中支持值类型,并且添加约束使得所有内容都变得神奇!