【问题标题】:Dart: doesn't override generic method has generic parameter type similar to the return typeDart:不覆盖泛型方法具有类似于返回类型的泛型参数类型
【发布时间】:2020-07-16 05:48:00
【问题描述】:

我在从抽象类覆盖泛型方法时遇到问题。

这是我的抽象类:

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

当我创建一个类 (B) 来实现类 (A) 时,如下所示:

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 "";
  }
}

在 (getData) 方法中显示以下编译错误:

'B.getData' ('String Function(String)') 不是 'A.getData' ('String Function(Type)') 的有效覆盖。飞镖(无效覆盖)

在return语句中出现这个错误:

无法从方法“getData”返回“String”类型的值,因为它的返回类型为“String”。

当泛型类型类似于返回类型时,为什么我会收到与覆盖相关的错误,这让我感到困惑。就像我用 getData&lt;int&gt;(int key) 而不是 getData&lt;String&gt;(String key) 创建另一个类 (C) 时,一切都按预期工作:

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

    return "";
  }
}

如果我删除了如下所示的返回类型,那么对于类 (B),一切都会按预期工作:

class B implements A {

  @override
  getData<String>(String key) {

     return "";
  }
}

这是 Dart 设计中的一个问题,所以我可以意识到它,因为这种行为在 c# 语言中不存在?

DartPad 链接: https://dartpad.dev/ebc7e6361d0cf1c6afad2f52ab8ebcaa

【问题讨论】:

标签: flutter dart generic-method


【解决方案1】:

您编写的第一个方法是对名为Type 的类型参数的泛型,并具有返回类型String。也就是说,它是任何类型的函数 Type 返回 String 类型的东西。

第二种方法是对名为String 的类型参数的泛型,并返回类型参数类型的某些内容。类型参数 named String 的事实使您看起来在第一个方法和第二个方法中具有相同的返回类型,但您没有。第一种方法返回String。第二种方法的返回类型为“刚刚引入的类型变量,名称为String”。这两种类型不相关,因此覆盖无效。如果将第二种方法中的类型变量重命名为T,则得到如下等效方法:

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

现在应该清楚为什么您的覆盖无效了。

【讨论】:

  • 感谢您的回复,我已附上带有代码的 DartPad 链接即使我将“Type”更改为“T”,我也会收到同样的错误。
  • 谢谢,现在有意义了。
【解决方案2】:

方法签名

String getData<Type>(Type key);

因为Type already has a meaning,所以更通常使用T 而不是Type。

String getData<T>(T key);

此签名用于允许为T 填写任何类型的方法。这意味着每个子类都必须有一个允许any类型T的方法。

我怀疑您想要的是将子类专门化为单个泛型类型 - 在这种情况下,您希望将泛型从方法级别移动到类级别。

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) => '';
}

【讨论】:

  • 感谢您的回复,我已附上 DartPad 链接,其中包含我不想将泛型从方法级别移动到类级别的代码。我在这里提出问题的想法是,我怀疑 Dart 的设计中存在错误,以覆盖具有相同类型返回类型的泛型方法。我试过你的解决方案,我有另一个,我稍后会记录它
  • 见叶的回答。当您写String getData&lt;String&gt;(String key) 时,与写T getData&lt;T&gt;(T key) 相同。您不能在返回类型 和 泛型类型参数 String 中使用“字符串”both 类型 String。使用&lt;String&gt; 和&lt;int&gt; 作为泛型类型参数是非常不寻常的。您几乎肯定不想创建具有非常常见类型名称的泛型参数,并且如果您想返回该类型,您不能这样做。解决方法是import 'dart:core' as core; 和core.String getData&lt;String&gt;(String key)。
  • 谢谢@Nata-Bosch,我可以用你提到的解决方法来解决它,Leaf 的回答现在对我来说很有意义
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
相关资源
最近更新 更多