在接口中使用事件是不好的做法吗? C#

问题描述 投票:1回答:2

我正在尝试更多地使用接口,而且我经常发现自己将事件放入接口。这感觉很奇怪,因为我要离开实施者,知道何时在实施过程中提出这些事件。

例如,我有一个ILevellable接口,它只是声明一个对象应该有xp,一个级别和一个最大级别,以及一些修改这些值的方法。引用ILevellable的类可能想知道它何时升级,所以我为OnLevelUp添加了一个Action ......但是实现可能不会将它放在正确的位置。

public interface ILevellable
{
    int Level { get; }
    int MaxLevel { get; }
    int XP { get; }
    event Action<bool> OnXPChanged;
    event Action<ILevellable> OnLevelUp;
    event Action OnMaxLevelReached;

    void LevelUp(int newLevel);
}

我是否应该相信实现此接口的用户将知道在哪里实现此功能?我不会假设。特别是因为某些事件可能有参数,用户可能也不知道应该代表什么。

我感谢任何指导!我是新手,像这样工作。

谢谢!

c# interface delegates
2个回答
1
投票

在接口中定义事件很好。然而,将'sender'和'event args'都传递给事件是符合惯例的。 TypedEventHandler是一种简单的方法。例如:

using Windows.Foundation;

public struct LevellableChange {
    public LevellableChange( int dl, int dxp) 
    { 
         this.ChangeInLevel = dl;
         this.ChangeInXP = dxp;
    }
    int ChangeInLevel { get; }
    int ChangeInXP {get;}
}

public interface ILevellable
{
    int Level { get; }
    int MaxLevel { get; }
    int XP { get; }
    event TypedEventHandler< ILevellable, LevellableChange> Changed;
}

然后实现它们的标准方法是这样的:

public class Levellable: ILevellable
{
    public event TypedEventHandler<ILevellable, LevellableChange> Changed;

    public int Level {
        get {
            return this._level;
        }
        private set {
            if (value != this._level) {
                int oldLevel = this._level;
                this._level = value;
                this.Changed?.Invoke(this, new LevellableChange(value - oldLevel, 0));
            }
        }
    }
    private int _level;

    // similar for XP. 
}

另一个注释,让一个实现INotifyPropertyChanged的类很有用,然后养成从中派生的习惯。与Visual Studio中的代码段一起使事情变得更加容易。确实,对于上面的示例,INotifyPropertyChanged是不够的,因为它不会给前一个值提供更改。


0
投票

首先,您的接口定义中没有委托类型,而是事件。检查Jon Skeet的this answer,看看代表和事件之间的区别。在说你的界面中有事件完全没问题之后,甚至.Net都会这样做,例如考虑着名的INotifyPropertyChanged界面。它只是定义了一个事件......

其次:

我是否应该相信实现此接口的用户将知道在哪里实现此功能?

当您定义一个接口时,您实际上并不关心实现者和消费者,因此,对于看到您的合同定义的消费者而言,知道他/她可以挂起名为OnLevelUp的事件是有用的。假设我确实正在使用你的界面,我不知道你是怎么或何时触发OnLevelUp事件,我不应该真的关心,因为你已经给了那个非常语义和有意义的名字,所以我几乎可以肯定它将在ILevellable的Level属性增加时触发。

© www.soinside.com 2019 - 2024. All rights reserved.