C# Foreach-根据列表中项目类型的不同说明<;福巴>;

C# Foreach-根据列表中项目类型的不同说明<;福巴>;,c#,polymorphism,C#,Polymorphism,我有一个接口类FooBar和两个具体类,Foo和Bar 如果我在FooBar中使用foreach,如何根据我的项目是Foo还是Bar使用不同的指令集?(例如,因为Foo和Bar没有相同的属性)。三个选项 如果可能,Foo和Bar应该有一个公共基类FooBarBase——或者实现一个公共接口,FooBar——它定义了一些虚拟方法,比如DoStuff()Foo和Bar每个机具DOSTUF()适当 因为你已经有了一个接口,你基本上就在那里 public interface FooBar { v

我有一个接口类
FooBar
和两个具体类,
Foo
Bar

如果我在
FooBar
中使用
foreach
,如何根据我的项目是
Foo
还是
Bar
使用不同的指令集?(例如,因为
Foo
Bar
没有相同的属性)。

三个选项

如果可能,
Foo
Bar
应该有一个公共基类
FooBarBase
——或者实现一个公共接口,
FooBar
——它定义了一些虚拟方法,比如
DoStuff()
Foo
Bar
每个机具
DOSTUF()
适当

因为你已经有了一个接口,你基本上就在那里

public interface FooBar {
    void DoStuff(SomeFrameworkThing x);
}

我不推荐这种方法;我推荐第一种方法,如果你坚持的话,也可以推荐第二种


(1) 我坐在这里看了一个小时的VisualStudio安装程序。目前,状态文本显示“无语法”

你能把代码贴出来吗?我想补充一点,这听起来好像你做错了什么。最有可能的情况是,您应该在接口中有一个方法,该方法在实现它的类中被重写,但不确定您在询问什么。你想让Foo和Bar都有一个名称相同但实现不同的方法吗?或者您想调用具有不同名称的方法(如
Foo.OneMethodName()
Bar.CompletelyDifferentMethodName()
)?在更具体的情况下,如果在同一列表中有Foo和Bar实例,每个类具有不同的属性,我想将这些属性赋予另一个对象(我无法修改的框架对象)。问题是,实例化另一个对象需要上下文数据(URL等),而FooBar对象不应该知道这些数据(如果我不是这样的话,我会使用FooBar接口的覆盖方法创建该项),使用后期绑定当然是一个选项,但我会先看看传统的OOP方法,只有当他们不适合求助于更深奥的。。。不是严厉的批评,只是观察。当您稍后添加另一个实现时,这可能会以有趣的方式失败,而将方法移动到接口并以不同的方式实现它将阻止它并引导实现者走向成功。@EdPlunkett第一个变体在最新版本的C#::
foreach(myFooAndBarList中的var o)开关(o)中看起来更好{case Foo Foo:fo.FooMethod();break;case Bar bo:bo.BarMethod();break;默认值:抛出新的NotSupportedException();break;}
@Sergey.quixoticaxis.Ivanov是的,我想到了。我在这里坐了一个小时,看着VS安装程序告诉我,我还不能用C#7来测试它。@EdPlunkett yeap,根据我个人的经验,如果你需要安装一些开发链,新的安装程序与旧的VS安装程序相比可能需要相当多的时间。@YthioCsi所有的DoStuff()方法都需要任意不同的输入吗?或者它们都工作在同一件事情上吗?如果是后者,那就是一个或多个参数。看看你最近对这个问题的评论,我会说:调用者使用URL等创建框架对象,将它传递给
public virtual X DoStuff(SomeFrameworkClass obj)
——其中X可能只是
void
。如果是前者,则您的逻辑无法通用化。您可以编写一个DoStuff()重载,该重载包含所有可能的参数,但以后可能需要一个新的参数。
List<FooBar> myFooAndBarList = new myFooAndBarList() { ... };

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

foreach (var fb in myFooAndBarList) {
    fb.DoStuff(thing);
}
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>>();
    }
}
public void DoStuff(Foo f) {
    //  stuff
}

public void DoStuff(Bar b) {
    //  other stuff
}
foreach (dynamic d in myFoAndBarList) {
    DoStuff(d);
}