如何摆脱这种代码重复,同时仍然保持优雅的事件
本文关键字:事件 何摆脱 代码 | 更新日期: 2023-09-27 18:09:57
假设我有两个类,A类和b类,它们都需要执行一个共同的操作,但让它们都从同一个对象派生是没有意义的,所以我们选择组合。基本上,"有一个"有意义,而"是一个"没有意义。
现在,两个类中的每一个都实例化了这个对象,并使用它来执行常见的操作,一切都很好。现在一切都好了。
当这两个类都必须公开一个公共例程必须引发的事件时,问题就出现了。哦哦。现在怎么办呢?
我们可以在这两个类中分别这样做:
public event EventHandler CommonEvent
{
add { theCommonObject.CommonEvent += value; }
remove { theCommonObject.CommonEvent -= value; }
}
但是现在这段代码需要在两个类中的每一个中复制,并且代码的读者也可能对这段代码感到困惑。至少add
和remove
不是很常见的关键字。
仍然,在两个类中都有重复的代码,不仅如此,而且这种解决方案并不总是有效!
例如,如果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
永远不能"在单个方法中局部实例化,它的作用域只在该方法内"。
是的,add
和remove
不常用。那又怎样?该类的客户端永远不会看到add
和remove
。它们仍然使用传统的+=
语法订阅事件。就客户端而言,add
和remove
语法不是问题。而你,作为创建类的开发者,应该知道这些东西
你可以使用静态助手一次获取代码,但它也'坏'
问题是实现可以一次写派生,你决定不派生。