为什么显式地将泛型强制转换为类类型有限制,但将泛型强制转换为接口类型没有限制?

Yur*_*han 18 c# generics

在阅读Microsoft文档时,我偶然发现了这样一个有趣的代码示例:

interface ISomeInterface
{...}
class SomeClass
{...}
class MyClass<T> 
{
   void SomeMethod(T t)
   {
      ISomeInterface obj1 = (ISomeInterface)t;//Compiles
      SomeClass      obj2 = (SomeClass)t;     //Does not compile
   }
}
Run Code Online (Sandbox Code Playgroud)

这意味着除非您有约束,否则可以显式地将通用转换为接口而不是类.好吧,我仍然无法理解决策背后的逻辑,因为接口和类类型转换都抛出异常,那么为什么只能防止这些异常中的一个呢?

BTW-有一种解决编译错误的方法,但这并没有消除我头脑中的逻辑混乱:

class MyOtherClass
{...}

class MyClass<T> 
{

   void SomeMethod(T t)

   {
      object temp = t;
      MyOtherClass obj = (MyOtherClass)temp;

   }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*röm 5

当你尝试在没有继承关系的类之间进行转换时,这正是你在正常情况下得到的 - 没有泛型 -

 public interface IA
 {
 }

 public class B
 {
 }

 public class C
 {
 }

 public void SomeMethod( B b )
 {
     IA o1 = (IA) b;   <-- will compile
     C o2 = (C)b;  <-- won't compile
 }
Run Code Online (Sandbox Code Playgroud)

因此,没有约束,泛型类的行为就好像类之间没有关系一样.

继续...

好吧,让我们说有人这样做:

 public class D : B, IA
 {
 }
Run Code Online (Sandbox Code Playgroud)

然后打电话:

SomeMethod( new D() );
Run Code Online (Sandbox Code Playgroud)

现在你将看到为什么编译器允许接口转换通过.如果实现了接口,它实际上无法在编译时知道.

请记住,D类可能很好地由使用你的程序集的人编写 - 在编译之后的几年.所以编译器不可能拒绝编译它.必须在运行时检查它.