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

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

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

这意味着您可以将通用代码显式地转换为该接口,但不能转换为类,除非您有约束。那么,我仍然不能理解这个决定背后的逻辑,因为界面和类类型的抛出都抛出异常,所以为什么只能保护这些异常之一呢?

BTW-有一个方法围绕编译错误,但这并不会消除我的头脑中的逻辑混乱:

class MyOtherClass
{...}

class MyClass<T> 
{

   void SomeMethod(T t)

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

   }
}
最佳答案
这正是你在正常情况下获得的 – 没有泛型 – 当你尝试在没有继承关系的类之间进行转换时:

 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
 }

所以没有约束,通用类将表现为类之间没有关系。

继续…

嗯,让我们说有人这样做:

 public class D : B, IA
 {
 }

然后打电话:

SomeMethod( new D() );

现在您将看到为什么编译器允许接口转换通过。如果一个接口被实现,它在编译时真的不知道。

请记住,D类可能是由使用您的程序集的人写的 – 在您编译之后的几年。所以编译器没有机会拒绝编译它。必须在运行时检查。

转载注明原文:c# – 为什么显式地将泛型转换为类类型有限制,但是没有限制将泛型转换为接口类型? - 代码日志