如果我不能(似乎)使用它(泛型),我很难理解为什么我可以使用这样的有界通配符。

如果我在一个类中有一个通配符字段,则不能使用具有已实现接口的通用参数的任何方法(除非我提供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());

09-11 06:26