繁体   English   中英

将枚举元素作为事件args C#传递

[英]Pass enum elements as event args C#

是否可以将Enum元素作为事件参数传递?

假设我有..

public class Letters
{
    public delegate void StateChangedEventHandler(object sender, EventArgs e);
    public event StateChangedEventHandler StateChanged;

    public AbcState state = AbcState.Aaa;     
    public AbcState State
    {
        get{return this.state;}
        set
        {
            this.state = value;
            this.OnStateChanged();
        }
    }

    public enum AbcState
    {
        Aaa,
        Bbb,
        Ccc
    }

    protected virtual void OnStateChanged()
    {
        StateChanged?.Invoke(this, State);
    }

看到我如何尝试将枚举的元素作为事件参数传递吗? 现在,我通常会创建一个类并扩展EventArgs,然后可以传递该类本身。 我知道我可以在这里做同样的事情,创建一个扩展EventArgs的不同类,然后在该类中创建枚举,字段和属性。 然后将后者的实例放入我的类“ Letters”(在上面的代码中使用)。

但是,那不疯狂吗? 一定有更好的方法。 请告诉我有一个简单的方法。

顺便说一下,我不知道上面的代码是否可以编译,因为我现在不在开发计算机中,所以我只是直接在编辑器中编写了代码。

如果您希望事件的参数为枚举,那么可以肯定的是,在声明事件时只需将其指定为签名即可:

public class Letters
{
    public event Action<AbcState> StateChanged;

    private AbcState state = AbcState.Aaa;     
    public AbcState State
    {
        get{return this.state;}
        set
        {
            this.state = value;
            this.OnStateChanged();
        }
    }

    public enum AbcState
    {
        Aaa,
        Bbb,
        Ccc
    }

    protected virtual void OnStateChanged()
    {
        StateChanged?.Invoke(State);
    }
}

不,那不是那么疯狂。 遵循约定并不是什么疯狂的事情,即使它们有时看起来有些笨拙,因为那样的话,那些维护您的代码的人(包括您,在您忘记编写这些东西之后就包括您)将发现尽可能少的惊喜。

您可以选择使用EventHandler<T> ,但是:

public event EventHandler<AbcState> StateChanged;

protected void OnStateChanged(AbcState state)
{
    StateChanged?.Invoke(this, state);
}

顺便说一句,您不必声明新的冗余委托类型即可声明事件。 这与您的原始声明相同:

public event EventHandler StateChanged;

最好的事情是写这样的东西:

public class ValueEventArgs<T> : EventArgs
{
    public ValueEventArgs(T value)
    {
        Value = value;
    }

    public T Value { get; protected set; }
}

并像这样使用它:

public event EventHandler<ValueEventArgs<AbcState>> StateChanged;

protected void OnStateChanged(AbcState state)
{
    StateChanged?.Invoke(this, new ValueEventArgs<AbcState>(state));
}

您还可以编写具有旧值和新值属性等的ValueChangedEventArgs<T> ,等等。但是EventHandler<AbcState>是执行所需操作的最快类型安全方式。

最后, 可以Action<T>用作event委托,但这不是一个好主意。 人们看到Action<T> ,但他们并不希望这是一个event 您唯一要添加的就是当有人尝试读取您的代码时感到困惑。 除非有一些明确的明显优势(这里没有),否则不要编写乍一看似乎不是的代码。

没有什么可以阻止您不遵循事件处理程序约定:

public enum Test { X }

public class A
{
    public event Action<Test> StuffDone;    
}

您将可以执行以下操作:

A a = new A();
a.StuffDone += test =>
{
    if(test == Test.X)
    {

    }
};

这只是一个约定,不是语言限制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM