泛型作为类型参数行为

时间:2018-12-20 06:53:23

标签: c# generics covariance invariance

这个问题已经有一段时间以不同的形式出现了,但是我没有找到很好的解释。

因此,在C#中,让我们考虑一下我有一个接口:

interface ITest<T>
{
}

然后,我有一个实现它的类:

class TestClass<T> : ITest<T>
{
}

现在,如果我创建具有以下签名的方法:

void TestMethod<T>(TestClass<ITest<T>> tt)
{
}

并尝试使用以下参数调用它:

...
var testParam = new TestClass<TestClass<int>>();
TestMethod(testParam);
...

它给出了编译时“无法转换”的类型错误。尽管实现接口的类应与接口类型本身兼容分配。 (这里我不考虑方差,因为在我的示例类中考虑的类参数与接口具有相同的类型参数)。
当然,我可以作一些欺骗,并做到以下几点:

void TestMethod<TVariant, TInterface>(TestClass<TInterface> tt)
where TInterface : ITest<TVariant>
{
}
....
....
var testParam = new TestClass<TestClass<int>>();
TestMethod<int, TestClass<int>>(testParam);
...

但是,这杀死了类型参数的推断(也就是说,您不能从方法调用中删除(int,TestClass(int))),并且代码变得杂乱无章,没有明确的类型实参规范。

所以,我有两个问题:

  1. 能做些什么来克服这种问题吗?我的意思是,将实现接口的类型用作类型参数,而将普通接口用作类型参数?
  2. 这是怎么回事?这样的编译时约束的确切原因是什么?仅仅是技术上的限制,还是我要实施的行为有任何警告?

0 个答案:

没有答案