繁体   English   中英

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

[英]c# Why can't open generic types be passed as parameters?

为什么不能打开通用类型作为参数传递。 我经常有类似的课程:

public class Example<T> where T: BaseClass
{
   public int a {get; set;}
   public List<T> mylist {get; set;}
}

可以说BaseClass如下;

public BaseClass
{
    public int num;
}

然后,我想说一种方法:

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;
}

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

public interface IExample
{
public int a {get; set;}
public IEnumerable<BaseClass> myIEnum {get;}
}

然后必须将通用类修改为:

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;} }
}

对于我本来以为编译器可以推断出的内容,这是很多仪式。 即使某些事情无法更改,但如果我知道缺少语法快捷方式的原因/理由,我发现它在心理上非常有帮助。

我也遇到过类似的情况,但是我从来没有遇到过这个问题(很好!)。 现在,我被迫考虑一下,这是我的答案:

您期望以下工作:

void F(Example<> e) {
   Console.WriteLine(e.a); //could work
}

是的,从理论上讲,这是可行的,但这不会:

void F(Example<> e) {
   Console.WriteLine(e.mylist); //?? type unknown
}

您希望编译器和CLR能够分析方法主体,并证明在第一种情况下实际上不可能进行不安全的访问。 可以做到这一点 为什么不呢 该设计可能并不真正合理且令人困惑。 另外,“默认情况下,所有功能都未实现。必须有人实现,测试和记录它们。”

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

一种实现的基本原理:支持此要求将所有非私有泛型类方法都设为虚拟,否则将无法得知哪种特定方法需要调用“开放”泛型类型。 不同的封闭类型方法有不同的布局,具有不同的对应方法指针。 手动定义接口相当于指示编译器必须将哪些方法视为虚拟方法,并且还允许您确切指定要公开的“开放”功能的哪个子集。 您基本上要提出的建议是,所有通用类都有一个为其公共接口的“开放”部分隐式生成的接口类,即使从不使用此功能,也将对该类产生性能影响。

也许我不明白您的确切问题,但是您可以通过这样声明它来使“ MyArbitrarySumMethod”采用任意示例:

public int MyArbitarySumMethod<T>(Example<T> example) where T : BaseClass

然后,您可以在不指定“ T”的情况下调用它:

int sum = MyArbitrarySumMethod(myExampleInstance);

那是您要找的东西吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM