4

我有以下类,它允许某些对象订阅更改事件。问题是我还有 B 类和 C 类,它们需要允许对象订阅相同类型的功能。我们当然不想复制和粘贴这种行为。

我们考虑过从一个公共基类继承,但是我们所有的类,包括 A、B 和 C 都已经从一个公共 BaseClass 继承。而且我们不想将此行为添加到 BaseClass 中,因为从 BaseClass 继承的其他类 E、F、G 不需要此行为。

有更好的解决方案吗?

public class A : BaseClass
{

    /*other properties and code */

    public event EventHandler OnChange;
    private bool _hasChanged;
    public bool HasChanged
    {
        get { return _hasChanged; }
        set
        {
            _hasChanged = value;
            //only need to notify when we've changed.
            if (value)
            {
                if (OnChange != null)
                    OnChange(this, EventArgs.Empty);
            }
        }
    }
}
4

4 回答 4

4

考虑一种面向方面的编程方法,例如PostSharp 示例中使用的方法。它将允许您使用属性注入那种样板代码。

如果您创建了适当的方面,则可以使用如下代码:

public class A : BaseClass
{
    public event EventHandler OnChanged;

    [ChangedNotify("OnChanged")]
    public bool HasChanged { get; set; }
}

或者,如果想法是为多个属性设置一个OnChange事件,您可以将其硬编码到方面,将您的代码减少到

public class A : BaseClass
{
    [NotifyOnChanged]
    public bool HasChanged { get; set; }
}
于 2010-11-23T00:11:56.940 回答
2

如果我们暂时不使用继承会怎样?

1-假设,不是从公共基类继承,而是将需要事件机制的客户端类与实现事件机制的对象组合在一起。

假设我们的班级是

 public class EventNotifier
{
    public event EventHandler OnChange;
    private bool _hasChanged;
    public bool HasChanged
    {
        get { return _hasChanged; }
        set
        {
            _hasChanged = value;
            //only need to notify when we've changed. 
            if (value)
            {
                if (OnChange != null)
                    OnChange(this, EventArgs.Empty);
            }
        }
    }
}

2-

 public class A
{
    private EventNotifier eventNotifier;
    public EventNotifier MyEventNotifier { get { return eventNotifier; } }

    public A()
    {
        eventNotifier = new EventNotifier();
    }


}

3-现在您的A类用户(继承的类/组成的A类)

这是因为如果 B 包含 A

 public class b
{
    A obj ;
    public b()
    {
        obj = new A();
        obj.MyEventNotifier.OnChange += new EventHandler(delegate { Console.WriteLine("Hi"); });
        obj. MyEventNotifier.HasChanged = true;
    }
}
于 2010-11-23T05:17:38.420 回答
1

您可以考虑在 BaseClass 和 A、B、C 之间引入一个包含常见行为的中间类。通过这种方式,您不会污染不需要该行为的 E、F、G。

             BaseClass
  -----------------------------
  |                           |
-----                   NotifyBaseClass
E,F,G                         |
                            -----
                            A,B,C

NB虽然 AOP 看起来不错,但我在尝试让 Postsharp 与其他技术(例如 MS 代码分析和 MSBuild)一起工作时遇到了重大问题。

于 2010-11-23T02:10:34.837 回答
0

为可通知对象创建一个子类可能是一种可行的方法,但如果将方面以这种方式乘以各种不同的类,则可能会很棘手。另一种方法是将其包含在您的基类中并为其定义一个接口,然后您可以简单地为相关类添加接口。

运行时,您只需检查它是否是 IChangeable (或其他东西),然后只连接到事件

于 2010-11-23T03:11:24.037 回答