如何摆脱这种代码重复,同时仍然保持优雅的事件

本文关键字:事件 何摆脱 代码 | 更新日期: 2023-09-27 18:09:57

假设我有两个类,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);
    }
}

可以看到,在这两种情况下都有重复的代码,但在第二种情况下甚至更多,因为对象是方法的局部而不是成员变量。

除了使用继承之外,我实在想不出其他方法来解决这个问题,但我认为这样做在语义上没有意义,而且许多人经常声称组合在降低复杂性、易于理解等方面优于继承。

如何摆脱这种代码重复,同时仍然保持优雅的事件

你说你有一个"has-a"关系。由此,并基于您提出的重复代码的解决方案,我假设您的类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语法不是问题。而你,作为创建类的开发者,应该知道这些东西

你可以使用静态助手一次获取代码,但它也'坏'

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