第三方类的多态扩展 [英] polymorphic extension to 3rd party classes

查看:106
本文介绍了第三方类的多态扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的情况是我有一个IEnumerable,我需要对其进行迭代并针对每个项目执行一些代码.

I have a situation where I have an IEnumerable which I need to iterate through and execute some code against each item.

要执行的代码取决于项目的实际类型,而我正在寻找的是一种很好的干净方法,无需任何条件,因此,如果我需要处理的派生类型数量增加,我只会需要编写一个新的处理程序,而不更改任何现有代码.

This code to be executed is dependent on the actual type of the item, and what I am looking for is a good clean way of doing this without any conditionals, so if the number of derived types I need to handle increases I simply need to write a new handler and not change any of my existing code.

为了说明这一点,我有一个示例,其中第3方库包含以下代码:

To illustrate this I have the example where the 3rd party library contains the following code:

public abstract class BaseObject{    }

public class Derived1: BaseObject { }

public class Derived2 : BaseObject { }

而我的本地代码则类似于:

and my local code does something like:

void Execute(IEnumerable<BaseObject> list)
{
    foreach (var item in list)
        item.DoWork();
}

我已经尝试创建扩展方法来做到这一点:

I have tried creating extension methods to do this:

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的扩展方法.

which obviously doesn't work as each item in the enumeration is of type BaseObject, so the extension method that returns 0 is always called.

我可以选择为每个派生类型都创建一个新的派生类型,所有实现接口:

I have the option of creating a new derived type for each derived type all implementing an interface:

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();
}

然后我可以迭代并投射到新界面:

then I could iterate and cast to the new interface:

void Execute(IEnumerable<BaseObject> list)
{
    foreach (var item in list)
    {
       var local = item as IMyInterface;
       local?.DoWork();
    }
}

但是这需要构造我的派生类型,而关于构造哪种类型的决定仍然需要一个条件语句,对于添加的任何新类型,该条件语句都需要更改.

but this requires construction of my derived type, and the decision as to which type to construct still requires a conditional statement which would need to change for any new type added.

这里清楚地使用了工厂模式,这是我到目前为止所拥有的最干净的解决方案.

Clearly use of the factory pattern here, and its the cleanest solution I have so far.

命令模式提供了一种解决方案,但是由于要执行的命令取决于派生类型的类型,因此仍然需要一个条件来构造此命令...

The command pattern offers a solution, but as the command to execute is dependent on the type of the derived type, a conditional is still needed to construct this command...

有人能建议一种方法,当将新的派生类型添加到组合中时,该方法将完全消除所有需要更改的条件吗?

Can anyone suggest an approach that would completely eliminate any conditional that would need changing when new derived types are added to the mix?

推荐答案

您可以使用dynamic.通常我不喜欢它,但是在这种情况下,这似乎是个不错的选择.

You could use dynamic. Normally I'm not a fan of it, but in this case it seems to be a good option.

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
    }
}

这篇关于第三方类的多态扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆