不必要的飞镖

时间:2019-06-24 11:27:51

标签: flutter syntax dart code-design

考虑到以下方面:

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()(像雨燕一样)

或一些编码准则,这些准则将来会帮助我编写更好的设计。

2 个答案:

答案 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
}
相关问题