我的一位同事在一个内部论坛上发布了一个问题,让我思考这是否可以通过C#实现。基本上,他有一个如下界面:
public interface IProvider<T>
{
T GetT();
}
是否可以使用实现该接口的东西作为另一个泛型类的类型参数,并且可以访问类型T而无需重新指定它?例如:
public class Foo<P> where P : IProvider<T>
{
P p;
T GetInnerT() { return p.GetT(); }
}
这不编译,因为类型T未定义,因此不能用作IProvider
的参数。这样的事情甚至可能吗?好奇!
答案 0 :(得分:6)
不,他需要Foo
在P 和 T中都是通用的:
public class Foo<P, T> where P : IProvider<T>
否则T
约束没有IProvider<T>
要注意 - 事实上它是IProvider<T>
声明的一部分是巧合。上述声明中的T
与T
中的IProvider<T>
完全分开(从编译器的角度来看)。例如,这将是一个等效的声明:
public class Foo<TProvider, TProvided> where TProvider : IProvider<TProvided>
要记住的另一件事是IProvider<T>
的实现可以为不同的类型参数多次实现它:
public class BigProvider : IProvider<string>, IProvider<int>, IProvider<char>
现在Foo<BigProvider>
是什么意思?这将是模棱两可的......而在我上面的声明中,你会做:
var x = new Foo<BigProvider, int>();
表示BigProvider
的提供方面。
答案 1 :(得分:2)
不,这是不可能的,因为在声明T
时,您的定义不允许提供Foo
类型。考虑:
var x = new Foo<string>();
在这种情况下,T
是什么?在编译时或运行时都无法知道。
正如您自己所说:未定义类型T
,并且要使类有效,您必须提供定义方法。例如:
public class Foo<P, T> where P : IProvider<T>