好吧,假设我有两个类,A类和B类.它们都需要执行一个常见的操作,但是让它们都来自同一个对象是没有意义的,所以我们选择组合.基本上,“有一个”是有意义的,而“是一个”不是.
现在,这两个类中的每一个都实例化该对象并使用它来执行常见操作,一切都很好.现在一切都很好.
当这两个类中的每一个都必须暴露公共例程必须引发的事件时,就会出现问题.哦,哦.怎么办?
好吧,我们可以在两个类中的每个类中执行类似的操作:
public event EventHandler CommonEvent
{
add { theCommonObject.CommonEvent += value; }
remove { theCommonObject.CommonEvent -= value; }
}
但是现在这个代码需要在两个类中的每个类中重复,代码的读者也可能会对此代码感到有些困惑.添加和删除不是很常见的关键字,至少.
尽管如此,这两个类中都存在重复的代码,不仅如此,但这个解决方案并不总是有效!
例如,如果CommonObject在单个方法中进行本地实例化,并且其范围仅在该方法内,该怎么办?
那么,在那种情况下,我们甚至无法使用之前发布的快捷代码,我们必须完全复制这两个类中的代码.不仅如此,它只是尖叫不合时宜,因为我们基本上只是将一个事件的副本重新提升给客户.
在这种情况下,必须在每个类中重复的示例代码:
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);
}
}
正如您所看到的,在两种情况下都存在重复的代码,但在第二种情况下甚至存在更多代码,因为该对象是方法的本地而不是成员变量.
除了使用继承之外,我无法想到解决这个问题的方法,但我不认为这样做会产生语义意义,并且许多人经常声称组合在复杂性降低,易于理解方面优于继承等等.
最佳答案 你说你有一个“有一个”的关系.从那以后,根据您提出的复制代码的解决方案,我假设您的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永远不能“在单个方法中进行本地实例化,其范围仅在该方法中”.
是的,添加和删除不常用.所以呢?该类的客户端永远不会看到添加和删除.他们仍然使用traditional =语法订阅该事件.就客户而言,添加和删除语法不是问题.而你,正在创建课程的开发人员,应该知道这些事情.