如何在保持优雅事件的同时摆脱这种代码重复?

时间:2011-09-27 21:26:15

标签: c# events

好的,假设我有两个类,A类和B类。它们都需要执行一个常见的操作,但是让它们都来自同一个对象是没有意义的,所以我们选择组合。基本上,“有一个”是有意义的,“是一个”不是。

现在,这两个类中的每一个都实例化了这个对象,并使用它来执行常见操作,一切都很好。现在一切都很好。

当这两个类中的每一个都必须暴露公共例程必须引发的事件时,就会出现问题。哦,哦。现在怎么样?

嗯,我们可以在两个类中的每个类中执行类似的操作:

public event EventHandler CommonEvent
{
    add { theCommonObject.CommonEvent += value; }
    remove { theCommonObject.CommonEvent -= value; }
}

但是现在这个代码需要在两个类中的每个类中重复,代码的读者也可能会对此代码感到有些困惑。 addremove至少不是常见的关键字。

尽管如此,这两个类中都存在重复的代码,不仅如此,但此解决方案并不总是有效!

例如,如果theCommonObject在单个方法中进行本地实例化,并且其范围仅在该方法中,那该怎么办呢。

那么,在那种情况下,我们甚至无法使用之前发布的快捷代码,我们必须完全复制这两个类中的代码。不仅如此,它只是尖叫不雅,因为我们基本上只是将一个事件的副本重新提升给客户。

在这种情况下,每个类中必须重复的示例代码:

public event EventHandler SomeCommonEvent;

private void SomeMethod()
{
    theCommonObject = new theCommonObject();

    theCommonObject.DoSomething();

    theCommonObject.SomeCommonEvent += thisClass_SomeCommonEvent;
}

private void thisClass_SomeCommonEvent(object sender, EventArgs e)
{
    var handler = SomeCommonEvent;

    if (handler != null)
    {
        handler(this, e);
    }
}

正如您所看到的,在这两种情况下都存在重复的代码,但在第二种情况下还有更多的代码,因为该对象是方法的本地而不是成员变量。

除了使用继承之外,我无法想到解决这个问题的方法,但我不认为这样做会产生语义上的意义,并且许多人经常声称组合在复杂性降低,易于使用方面优于继承。理解等等。

2 个答案:

答案 0 :(得分:2)

你说你有一个“有一个”的关系。从那以后,根据您提出的复制代码的解决方案,我假设您的A类看起来像:

public class A
{
    private SomeCommonObject theCommonObject;
    public event EventHandler CommonEvent
    {
        add { theCommonObject.CommonEvent += value; }
        remove { theCommonObject.CommonEvent -= value; }
    }

    public A()
    {
        theCommonObject = new SomeCommonObject();
    }
}

问题出在哪里? theCommonObject永远不能“在单个方法中进行本地实例化,其范围仅在该方法中。”

是的,addremove并不常用。所以呢?该类的客户端永远不会看到addremove。他们仍然使用传统的+=语法订阅该事件。就客户而言,addremove语法不是问题。而你,正在创建课程的开发人员,应该知道这些事情。

答案 1 :(得分:0)

您可以使用静态助手来获取代码一次但它也是“坏”

问题是实现可以用派生编写一次,你决定不派生。