显式转换运算符,泛型,继承和接口

时间:2010-07-08 20:34:43

标签: c# .net-3.5

这似乎不起作用。有可能吗?

public interface IInterface1 {}
public interface IInterface2 { }

public interface IMyT1 : IInterface1 {}
public interface IMyT2 : IInterface2 {}

public abstract class BaseClass<T1, T2> : Interface2 where T1 : IInterface1, where T2 : IInterface2
{
     protected T1 T1Obj {get;set;}

     public static explicit operator T1(BaseClass<T1,T2> val)
     {
          return val.T1Obj;
     }
}

public class SomeClass : BaseClass<IMyT1, IMyT2>, ISomeClass {}

对SomeClass的任何强制转换都会失败并显示InvalidCastException

ISomeClass mySomeClass = new SomeClass();
var myT1 = (IMyT1)mySomeClass; //Boom!

这可能很疯狂,但有可能吗?

2 个答案:

答案 0 :(得分:2)

您正在寻找的是通用差异。至少,我假设 - 您的示例代码缺少我们需要的位,以便检查实际上是否正常工作。

您无法在C#3及更早版本中使用它。在C#4中,您可以将它用于接口和委托,但只有在类型参数上使用inout明确标记的情况下 - 编译器才能确保它基本上都是安全的。

如果您在本网站上搜索通用差异或协方差和逆变,您会发现大量信息。或者您可以查看Eric Lippert's blog series。我在C# in Depth的第13章中提供了详细信息,如果您在NDC 2010 streaming video site上搜索“协方差”,您可以流式传输或下载我就此主题发表的长达一小时的演讲。

答案 1 :(得分:1)

您的对象不属于IMyT1类型,这就是转换失败的原因。

这些是您的有效转换......

var instance = new SomeClass();
var localInterface = (ISomeClass)instance;
var baseClass = (BaseClass<IMyT1, IMyT2>)instance;
var baseInterface = (IInterface2)instance;

... instance不属于IMyT1IMyT2IInterface1类型。试图转换为任何一个将失败。如果BaseClassSomeClass继承自IMyT1,那么您就可以完成此转换。

同样静态方法在编译时解析,而在RunTime中考虑强制转换。这是您无法使用virtual static方法的原因之一。