隐式引用从引用类型到用户定义类型的接口的转换

时间:2013-02-08 22:03:38

标签: c#

来自C#4.0 Spec section 6.1.6:

  

隐式参考转换是:

     

[...]

     

从任何引用类型到接口或委托类型T(如果有)   隐式身份或引用转换为接口或   委托类型T0和T0是变量可转换(13.1.3.2)到T。

Vladimir Reshetnikov告诉我们,从List<string>IEnumerable<object>存在隐式参考转换。但是,如何将其应用于用户定义的类型(甚至可能)?

我尝试了一个隐式运算符,自定义派生类型和一些变量......但我无法重现scenerio。我有:

class Program
{
    static void Main(string[] args)
    {
        IEnumerable<object> specialClassConversion = new List<string>();
        IEnumerable<A> userdefinedTypeConversion = new List<B>();
        A implicitConversion = new B();//varience-convertible
        IC<A> explicitConversion = (IC<A>)new D<B>();//OK, varience-convertible
        IC<A> implicitConversion2 = new D<B>();//does not compile
    }
}

class A { }

class B : A { }

interface IC<T> { }    

class D<T> 
{
    //public static implicit operator IC(D<T> m)//Error: user-defined conversions to or from an interface are not allowed
    //{
    //    return null;
    //}
}

1 个答案:

答案 0 :(得分:3)

如果您希望用户定义的类或结构可以隐式转换为接口,请让您的类/结构实现该接口。

(编辑)

如果您希望IC<B>可以隐式转换为IC<A>,请通过指定{{IC<T>T中创建out接口协变 1}}关键字,interface IC<out T> { }。您给出的规范中的引用告诉我们这两个隐式转换的“组合”也是隐式转换。

<强>来源:

interface IC<out T> {  }

class D<T> : IC<T>  { }

(结束编辑)

关于List<string>类,它实现了IEnumerable<string>,而IEnumerable<object>又可以转换(隐式)到IEnumerable<out T>,因为out协变({ {1}}中的{1}}。

(他们不允许你创建一个转换为接口/从接口转出的T的一个原因是,somone可以写一个继承自你的类的派生类实现了界面。这会在他们的类和界面之间进行“自然”转换,但public static implicit operator也适用,导致两个转换(一个“自然”和一个“用户” - 类型之间的“定义”,这将是混乱和模糊的。)