Dart: doesn't override generic method has generic parameter type similar to the return type

拈花ヽ惹草 提交于 2020-07-22 21:37:45

问题


I have an issue to override a generic method from an abstract class.

Here is my abstract class:

abstract class A {
  String getData<Type>(Type key);
}

when I created a class (B) to implement class (A) as showing below:

class B implements A {
  @override
  String getData<String>(String key) {     //Error <= B.getData' ('String Function<String>(String)') isn't a valid override of 'A.getData' ('String Function<Type>(Type)')

    return "";
  }
}

Shown the below compilation error at (getData) method:

'B.getData' ('String Function(String)') isn't a valid override of 'A.getData' ('String Function(Type)'). dart(invalid_override)

And this error at the return statement:

A value of type 'String can't be returned from method 'getData' because it has a return type of 'String'.

It's confusing for me why I am getting this error related to the override when the generic type similar to return type. as when I created another class (C) with getData<int>(int key) instead of getData<String>(String key) everything works as expected:

class C implements A {
  @override
  String getData<int>(int key) {

    return "";
  }
}

Also with the class (B) if I deleted the return type as shown below everything will work as expected:

class B implements A {

  @override
  getData<String>(String key) {

     return "";
  }
}

Is it an issue in Dart design so I can be aware of it because this behavior does not exist in c# language for example?

DartPad Link: https://dartpad.dev/ebc7e6361d0cf1c6afad2f52ab8ebcaa


回答1:


The first method you wrote is generic over a type parameter named Type, and has return type String. That is, it is the function which for any type Type returns something of type String.

The second method, is generic over a type parameter named String, and returns something of the type parameter type. The fact that the type parameter is named String makes it look like you have the same return type in the first method and the second, but you don't. The first method has a return to of String. The second method has a return type of "the type variable that was just introduced and has name String". Those two types are unrelated, and so the override is invalid. If you rename the type variable in the second method to T, you get the following equivalent method:

class B implements A {
  @override
  T getData<T>(T key) {
    return "";
  }
}

and it should now be clear why your override is invalid.




回答2:


The method signature

String getData<Type>(Type key);

Would more typically be written with a T instead of Type, since Type already has a meaning.

String getData<T>(T key);

This signature is for a method that allows any type to be filled in for T. This means that every subclass must have a method that allows for any type T.

I suspect that what you want is for subclasses to be specialized to a single generic type - in that case you want to move the generic from the method level to the class level.

abstract class A<T> {
  String getData(T key);
}

class B implements A<String> {
  @override
  String getData(String key) => '';
}

class C implements A<int> {
  @override
  String getData(int key) => '';
}


来源:https://stackoverflow.com/questions/61022367/dart-doesnt-override-generic-method-has-generic-parameter-type-similar-to-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!