2017-08-02 142 views
3

我在使用隐式转换和IEnumerable时遇到了一个有趣的情况 - 请看附加代码的最后一行 - 它不会编译。隐式转换IEnumerable转换为泛型

public class Outer<T> 
{ 
    private T field; 
    public Outer(T it) 
    { 
     field = it; 
    } 

    public static implicit operator Outer<T> (T source) 
    { 
     return new Outer<T>(source); 
    } 
} 

void Main() 
{ 
    Outer<string> intsample = "aa"; 
    Outer<IList<object>> listsample = new List<object>(); 

    //The line below fails with: 
    //CS0266 Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<object>' 
    //to 'UserQuery.Outer<System.Collections.Generic.IEnumerable<object>>'. 
    //An explicit conversion exists (are you missing a cast?) 
    Outer<IEnumerable<object>> enumerablesample = Enumerable.Empty<object>(); 
} 

我有一个很强烈的直觉,它是兴高采烈的IEnumerable是协变,但也有人更正式的解释?

+0

为什么不直接投射? – Mafii

+0

因为这只是示例来显示问题,所以如果使用像LangugeExt和它的任一类型的库,隐式转换非常方便。不幸的是,我不明白将它标记为重复,并指出关于方差和遗传的不是如此相关的答案。 –

+0

@PatrickHofman我必须同意,这个问题不是直接由重复的答案。投票重新开放。 – Mafii

回答

2

The docs状态:

类或结构允许声明从源 型S转换至T提供的所有以下属实的目标类型:

  • S和T是不同的类型。
  • S或T是运算符声明发生的类或结构类型。
  • S和T都不是对象或接口类型。 T是不是一个基类的S,S是不是一个基类T的

简单的解决方法是改变:

Enumerable.Empty<object>(); 

到:

new List<object>(); 

这是因为List不是一个接口(谢谢@PatrickHofman!)。

+1

你只是重复可以在这里找到重复:https://stackoverflow.com/a/143567/993547 –

+3

它并不奇怪作品:'列表'不是一个接口,它是一个具体的类型。 –

+0

良好的通话 - 谢谢@PartrickHofman! – mjwills