Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在保持优雅事件的同时消除这种代码重复?_C#_Events - Fatal编程技术网

C# 如何在保持优雅事件的同时消除这种代码重复?

C# 如何在保持优雅事件的同时消除这种代码重复?,c#,events,C#,Events,好的,假设我有两个类,类A和类B。它们都需要执行一个公共操作,但是让它们都从同一个对象派生是没有意义的,所以我们使用合成。基本上,“有一个”是有意义的,而“是一个”没有意义 现在,这两个类中的每一个都实例化了这个对象,并使用它来执行公共操作,一切都很好。现在一切都好了 当这两个类中的每一个都必须公开公共例程必须引发的事件时,就会出现问题。哦。现在怎么办 好吧,我们可以在两个班中的每一个班上做类似的事情: public event EventHandler CommonEvent { ad

好的,假设我有两个类,类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);
    }
}
如您所见,在这两种情况下都有重复的代码,但在第二种情况下甚至有更多,因为对象是方法的局部对象,而不是成员变量

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

你说你有“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();
    }
}
问题出在哪里
CommonObject
永远不能“在单个方法中本地实例化,并且其范围仅在该方法中。”


是的,
添加
删除
不常用。那又怎么样?类的客户端从未看到
添加
删除
。他们仍然使用传统的
+=
语法订阅事件。就客户端而言,
add
remove
语法不是问题。而您,即创建类的开发人员,应该知道这些事情。

您可以使用静态帮助器一次性获取代码,但这也是“不好的”


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

谢谢您的回复。这是一个好主意,但是在我的实例中,在方法完成后,一些CommonObject必须超出范围并取消分配。此外,还有一个最初的问题,即此代码仍然需要在每个类中复制。如果
SomeCommonObject
超出范围,那么唯一的“问题”是不会有更多的通知来自它。我不认为这是个问题。只是不要将其存储在对象中。至于复制那几行代码。。。你期望它是免费的吗?嗯,这篇文章的全部目的就是想找到一个解决这个问题的方法。任何像这样的代码重复对我来说都很难闻。我必须将代码从一个类复制粘贴到另一个类。没有变化。根据你提供的信息,这是我能提出的最好建议。不过,我觉得,如果您提供多一点信息(例如,
SomeCommonObject
的局部范围有限的情况),我们可以想出一个更令人满意的替代方案。