如果我不能(似乎)使用它(泛型),我很难理解为什么我可以使用这样的有界通配符。
如果我在一个类中有一个通配符字段,则不能使用具有已实现接口的通用参数的任何方法(除非我提供null
作为参数)。
class SomeClass {}
class DerivedClass extends SomeClass {}
interface IInterf<T extends SomeClass> {
T returnsT();
void paramT(T parm);
T paramAndReturnT(T parm);
int nonGenericMethod(int x);
}
class Impl {
protected IInterf<?> field; //this is bound to <extends SomeClass>
//- it's implied by the definition
// of IInterf which is bound
// but what's the point?
public Impl(IInterf<? extends SomeClass> var){
field = var;
}
public void doSmth(){
SomeClass sc = field.returnsT(); //works
field.paramT(new SomeClass());
//error: method paramT in interface IInterf<T> cannot be applied to given types;
//required: CAP#1
//found: SomeClass
//reason: actual argument SomeClass cannot be converted to CAP#1 by method invocation conversion
//where T is a type-variable:
// T extends SomeClass declared in interface IInterf
//where CAP#1 is a fresh type-variable:
// CAP#1 extends SomeClass from capture of ?
field.paramT(null); //works
SomeClass sc2 = field.paramAndReturnT(new DerivedClass());
//error: method paramAndReturnT in interface IInterf<T> cannot be applied to given types;
// SomeClass sc2 = field.paramAndReturnT(new DerivedClass()); //required: CAP#1
//found: DerivedClass
//reason: actual argument DerivedClass cannot be converted to CAP#1 by method invocation conversion
//where T is a type-variable:
// T extends SomeClass declared in interface IInterf
//where CAP#1 is a fresh type-variable:
// CAP#1 extends SomeClass from capture of ?
//
int x = field.nonGenericMethod(5); //obviously works.
}
}
FWIW,我无法说服C#编译器接受类似的内容。
我想念什么吗?
最佳答案
当您将field
声明为
protected IInterf<?> field;
?
代表扩展SomeClass
的未知类。认为它不是通配符,而是作为派生SomeClass
但匿名的特定类。如果您现在尝试致电
field.paramT(new SomeClass());
之所以失败,是因为
SomeClass
实例与?
所代表的含义不兼容,即扩展SomeClass
的匿名类。使用
null
没问题,它与任何类都兼容。情况完全相同
SomeClass sc2 = field.paramAndReturnT(new DerivedClass());