Foreach - 不同的指令取决于List <FooBar>中的项目类型

Yth*_*Csi 4 c# polymorphism

我有一个接口类FooBar和两个具体的类,FooBar.

如果我foreachFooBar,我如何使用不同的指令集取决于我的项目是a Foo还是Bar?(例如,因为Foo并且Bar没有相同的属性).

15e*_*153 5

三种选择.

如果可能的话,Foo并且Bar应该有一个共同的基类FooBarBase- 或实现一个通用的接口,你的FooBar- 定义了一些虚拟方法,比方说DoStuff().Foo并且Bar每个都DoStuff()适当地实施

由于你已经有了一个界面,你基本上就在那里.

public interface FooBar {
    void DoStuff(SomeFrameworkThing x);
}
Run Code Online (Sandbox Code Playgroud)

...

List<FooBar> myFooAndBarList = new myFooAndBarList() { ... };

var thing = new SomeFrameworkThing(/* long list of murky parameters, all different */);

foreach (var fb in myFooAndBarList) {
    fb.DoStuff(thing);
}
Run Code Online (Sandbox Code Playgroud)

但是如果那是不可能的,或者你正在做的具体细节使它变得非常复杂(例如,你想让它们做完全不相关的东西),你就可以这样做.只需查看代码,您就可以了解为何选择上述版本.在C#7中,有更好的语法,但我还没有安装它来测试(1).

foreach (var o in myFooAndBarList) {
    if (o is Foo) {
        var f = o as Foo;
        f.FooMethod();
        f.FooProperty = "lol";
    }
    else if (o is Bar) {
        var b = o as Bar;
        b.BarMethod(234, 345);
        b.BarProp = new Dictionary<Foo, List<Bar>>();
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,你可以用奇怪的,深奥的,奇异的方式做到这一点dynamic:

public void DoStuff(Foo f) {
    //  stuff
}

public void DoStuff(Bar b) {
    //  other stuff
}
Run Code Online (Sandbox Code Playgroud)

...

foreach (dynamic d in myFoAndBarList) {
    DoStuff(d);
}
Run Code Online (Sandbox Code Playgroud)

试试吧.我不拉你的腿.我不推荐这种方法; 我建议使用第一种方法,如果您坚持使用第二种方法,可能会推荐第二种方法.

(1)我坐在这里观看Visual Studio安装程序一小时.目前,状态文本显示"NO SYNTAX FOR YOU".

  • 使用后期绑定当然是一种选择,但我会首先看一下传统的OOP方法,并且只有当它们不适合采用更深奥的方法时......不是一种严厉的批评,只是一种观察.当您稍后添加另一个实现时,这可能会以有趣的方式失败,而将方法移动到接口并以不同方式实现它会阻止它并指导实现者走向成功的道路. (2认同)
  • @EdPlunkett第一个变体看起来更好用最新版本的C#:`foreach(var o in myFooAndBarList)switch(o){case Foo fo:fo.FooMethod(); 打破; case bar bo:bo.BarMethod(); 打破; default:throw new NotSupportedException(); 打破; } (2认同)