c#为什么不能打开泛型类型作为参数传递?

Ric*_*ver 5 c# generics

为什么无法打开泛型类型作为参数传递.我经常上课:

public class Example<T> where T: BaseClass
{
   public int a {get; set;}
   public List<T> mylist {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

让我们说BaseClass如下;

public BaseClass
{
    public int num;
}
Run Code Online (Sandbox Code Playgroud)

然后我想要一种方法说:

public int MyArbitarySumMethod(Example example)//This won't compile Example not closed
{
   int sum = 0;
   foreach(BaseClass i in example.myList)//myList being infered as an IEnumerable
       sum += i.num;
   sum = sum * example.a;
   return sum;
}
Run Code Online (Sandbox Code Playgroud)

然后我必须编写一个接口,只是为了将这一个类作为参数传递,如下所示:

public interface IExample
{
public int a {get; set;}
public IEnumerable<BaseClass> myIEnum {get;}
}
Run Code Online (Sandbox Code Playgroud)

然后必须将泛型类修改为:

public class Example<T>: IExample where T: BaseClass
{
   public int a {get; set;}
   public List<T> mylist {get; set;}
   public IEnumerable<BaseClass> myIEnum {get {return myList;} }
}
Run Code Online (Sandbox Code Playgroud)

对于我认为编译器可以推断出的内容,这是很多仪式.即使某些事情无法改变,如果我知道缺少Syntax捷径的理由/理由,我发现它在心理上非常有帮助.

usr*_*usr 2

我也遇到过类似的情况,但我从未有过这个(非常好!)的问题。现在我不得不思考这个问题,这是我的答案:

您期望以下内容能够发挥作用:

void F(Example<> e) {
   Console.WriteLine(e.a); //could work
}
Run Code Online (Sandbox Code Playgroud)

是的,这在理论上是可行的,但这是行不通的:

void F(Example<> e) {
   Console.WriteLine(e.mylist); //?? type unknown
}
Run Code Online (Sandbox Code Playgroud)

您期望编译器和 CLR 能够分析方法体并证明在第一种情况下确实不可能存在不安全访问。这可以发挥作用。为什么不是呢?也许,这个设计并不健全并且令人困惑。此外,“默认情况下,所有功能均未实现。必须有人实现、测试并记录它们。”

编辑:我想指出,如果没有 CLR 的配合,这个功能就无法实现。C# 编译器必须发出要调用的确切方法,这在开放泛型类型上是不可能的。类型系统现在甚至不允许这样的变量。