如何“重新抛出”私人领域的事件?

时间:2012-03-25 20:49:05

标签: c# events

我需要附加到类的私有字段的事件:

MyClass myInstance = ...
... 
myInstance.checkbook.RangeMissing += new EventHandler<RangeMissingEventArgs>(RangeMissing);

要做到这一点,我必须做checkbook public。但是我想保留checkbook private,我只想捕捉“RangeMissing”事件。

所以我需要在事件RangeMissing的MyClass类中“重新抛出”吗?

当然我可以“明确地”(将MyClass附加到支票簿,捕获RangeMissing事件,抛出新的RangeMissing事件),但我觉得它太复杂了。

我有设计问题吗?我应该公开checkbook吗?我应该只编写10行额外代码,并在MyClass类中明确重新抛出事件吗?

3 个答案:

答案 0 :(得分:2)

我认为你有两种选择:

  1. 正如Tigran建议的那样,通过提出另一个事件来处理你班上的事件:

    class MyClass
    {
        public event EventHandler<RangeMissingEventArgs> CheckbookRangeMissing =
            delegate { };
    
        public MyClass()
        {
            // initialize checkbook
    
            checkbook.RangeMissing += OnCheckbookRangeMissing;
        }
    
        private void OnCheckbookRangeMissing(object sender, EventArgs e)
        {
            CheckbookRangeMissing(this, e)
        }
    }
    

    请谨慎使用此方法,因为如果checkbook的生命周期长于MyClass,则可能会导致内存泄漏。在这种情况下,您需要在完成MyClass时(可能采用Dispose()方法)取消订阅活动。

  2. 创建一个事件,将所有订阅者转发到checkbook上的活动:

    class MyClass
    {
        public event EventHandler<RangeMissingEventArgs> CheckbookRangeMissing 
        {
            add
            {
                checkbook.RangeMissing += value;
            }
            remove
            {
                checkbook.RangeMissing -= value;
            }
        }
    }
    

答案 1 :(得分:1)

您没有设计问题,至少从帖子中也看不到。 最简单,最直接的解决方案是imo,

  • 首先将checkbox保留为私人
  • MyClass内部重新引发从checkbox
  • 引发的事件

通过这种方式,您将隐藏一个复选框并向您的MyClass消费者展示一个事件。此外,如果需要,您可以更改代理人并向MyClasscheckbox事件参数不同的代理人传递给消费者。

希望这有帮助。

答案 2 :(得分:0)

我认为您需要的最佳解决方案是使用Rx - 如果您不害怕将新技术引入图片中(已经有一个相当稳定的版本并且已经获得了许可证) 即使用

IObservable<DataType> RangeMissing;

...由引用的私有字段的类实现(引发)。 然后父类只需要将它包装成一个非常简单的属性(公共)......

public IObservable<DataType> RangeMissing {get{return _privateField.RangeMissing;} }

......这是处理事件的最“绿色”方式,整个框架是为此目的而发明的(轻松操纵事件,不需要所有订阅/取消订阅和命令式编码 - 例如即使是像你这样的简单包装器成为一个问题,小问题,但需要编写不必要的代码) 您可以通过NuGet将Rx安装到项目中(适用于.NET 4,VS 2010)

这就是我认为从设计角度推荐的内容,
除此之外,您可能只想按照建议进行换行,或者为此目的制作更精细的包装器(但Rx做得更好) - 或重新考虑一些设计决策,类责任 - 或者是否通过特定实现公开事件等等(为此我们需要了解更多细节,每个设计都是具体的) 希望这有帮助