考虑到以下方面:
class Foo {}
class Bar extends Foo {}
class Baz extends Foo {}
我发现自己正在编写这种类型的代码:
if (foo is Bar) {
(foo as Bar).doSomething(); //Compiler warning of unnecessary cast.
} else (foo is Baz) {
(foo as Bar).doSomething(); //Compiler warning of unnecessary cast.
}
请告知,因为我不知道如何避免这种情况。
如果在投射前删除是Bar 或是Baz 的检查类型,我可能会遇到运行时错误,如果我不进行投射,则表示没有访问该类型的公共内容。
也许我遵循了有缺陷的代码设计,需要更新,因为我认为我应该避免检查类类型。
所以我的问题是:
飞镖中是否有任何语法糖可能对您有帮助
(foo as? Bar)?.doSomething()
(像雨燕一样)
或一些编码准则,这些准则将来会帮助我编写更好的设计。
答案 0 :(得分:2)
实际上,您只能执行foo.doSomething();
而不是(foo as Bar).doSomething()
。编译器知道,如果条件if(foo is Bar)
成立,则该代码块中的变量foo
的类型为Bar
。
尝试:
if (foo is Bar) {
foo.doSomething(); // It's automatically inferred that type of `foo` is `Bar`
} else if (foo is Baz) {
foo.doSomething(); // It's automatically inferred that type of `foo` is `Baz`
}
希望有帮助!
答案 1 :(得分:0)
对于面向对象的语言,这种基于类的if / else或switch语句是使用多态性解决的。如果doSomething()位于Foo中,则编译器将知道无论运行时类型如何,该方法都在Foo的任何子代上定义。
然后,如果您知道foo是Foo,Bar或Baz,则实际上应该只使用foo.doSomething(),而不进行类型检查和强制转换。
您唯一需要了解的是验证foo是否为Foo,请确保使用type而不是var或dynamic:
void doSomething(dynamic foo){
if (foo is Foo) {
foo.doSomething(); //Ok with Foo Bar or baz
}
foo.doSomething(); //Possible runtime error since foo can be anything
}
因为输入dart是一种使用类型而不是动态的好习惯,所以您可以直接编写以下内容:
void doSomething(Foo foo){ //Making sure that you will work with a Foo
foo.doSomething(); //Ok with Foo Bar or baz with no check
}