我遇到的情况是我有一个IEnumerable,我需要对其进行迭代并针对每个项目执行一些代码。
要执行的代码取决于项的实际类型,而我正在寻找的是一种没有任何条件的好方法,因此,如果我需要处理的派生类型数量增加,我只需要编写一个新的处理程序,而不更改任何现有代码。
为了说明这一点,我有一个示例,其中第三方库包含以下代码:
public abstract class BaseObject{ }
public class Derived1: BaseObject { }
public class Derived2 : BaseObject { }
我的本地代码执行类似以下操作:
void Execute(IEnumerable<BaseObject> list)
{
foreach (var item in list)
item.DoWork();
}
我尝试创建扩展方法来做到这一点:
public static class Extensions
{
public static int DoWork(this BaseObject obj) { return 0; }
public static int DoWork(this Derived1 obj) { return 1; }
public static int DoWork(this Derived2 obj) { return 2; }
}
这显然不起作用,因为枚举中的每个项目都是BaseObject类型的,因此始终调用返回0的扩展方法。
我可以选择为每个实现接口的每个派生类型创建一个新的派生类型:
public class MyDerived1: Derived1, IMyInterface
{
public int DoWork(){return 1;}
}
public class MyDerived2: Derived2, IMyInterface
{
public int DoWork(){return 2;}
}
public interface IMyInterface
{
int DoWork();
}
然后我可以迭代并投射到新接口:
void Execute(IEnumerable<BaseObject> list)
{
foreach (var item in list)
{
var local = item as IMyInterface;
local?.DoWork();
}
}
但这需要构造我的派生类型,而关于构造哪种类型的决定仍然需要条件语句,对于添加的任何新类型,该条件语句都需要更改。
显然,这里使用了工厂模式,这是我到目前为止提供的最干净的解决方案。
命令模式提供了一种解决方案,但是由于要执行的命令取决于派生类型的类型,因此仍然需要条件来构造此命令...
谁能建议一种方法,当将新的派生类型添加到组合中时,该方法将完全消除所有需要更改的条件?
最佳答案
您可以使用dynamic
。通常我不喜欢它,但是在这种情况下,这似乎是一个不错的选择。
public static class Worker
{
public static int DoWork(BaseObject obj) { return 0; }
public static int DoWork(Derived1 obj) { return 1; }
public static int DoWork(Derived2 obj) { return 2; }
}
void Execute(IEnumerable<BaseObject> list) {
foreach (dynamic item in list) {
Worker.DoWork(item); // Method resolution done at run-time
}
}
关于c# - 第三方类的多态扩展,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36354522/