为什么无法打开泛型类型作为参数传递.我经常上课:
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捷径的理由/理由,我发现它在心理上非常有帮助.
我也遇到过类似的情况,但我从未有过这个(非常好!)的问题。现在我不得不思考这个问题,这是我的答案:
您期望以下内容能够发挥作用:
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# 编译器必须发出要调用的确切方法,这在开放泛型类型上是不可能的。类型系统现在甚至不允许这样的变量。