我有这个非常简单的代码
abstract class Bar {
String name;
}
class Base {}
class Foo extends Base implements Bar {
String name;
}
void main() {
final Base foo = Foo();
if (foo is Bar) {
foo.name = 'a';
}
print(foo);
}
如果要实现对象,则要在其中设置对象的属性。但是运行它会失败,并显示错误
The setter 'name' isn't defined for the class 'Base'.
看起来好像if语句没有将foo强制转换为Bar,或者Bar没有设置器?
我该如何解决?
答案 0 :(得分:0)
Dart 类型提升(允许您使用与声明类型不同的类型的变量)无法处理这种情况。
Dart中的变量在任何时候都仅具有 one 类型。
如果您进行x is SomeType
测试,则编译器可以说服自己将变量视为新类型是绝对安全的,则变量可能会提升为SomeType
。 / p>
此规则的一部分是类型提升仅允许您提升为当前类型的子类型。这样一来,这是一项严格的晋升,您不会丢失已经拥有的信息。
您在此处尝试从Base
升级为Bar
,但是Bar
不是Base
的子类型。
因此,促销活动必须选择Base
或Bar
作为一个类型。两种选择都会丢弃信息(或者如果Base
具有无法在Bar
上调用的有用成员),则编译器必须做出选择。
因此,它将foo
的类型保留为Base
。
您可以改为使用if (foo is Foo)
进行测试,因为Foo
是Base
的子类型,并且具有name
的设置器。
或者您可以创建可升级变量并对其进行推广:
Object obj = foo;
if (obj is Bar) foo.name = "a";
之所以可行,是因为从Object
升级到Bar
是对子类型的升级。
或者您可以投射:
if (obj is Bar) (obj as Bar).foo = "a";
这看起来有些多余。希望编译器可以说服自己,没有理由进行第二次检查。