使用Action或Func之类的事件 - 糟糕的做法?

时间:2016-04-20 14:09:21

标签: c#

我检测到C#的功能,可以像事件一样使用Action或Func。我的意思是,我可以做到:

Action aAction;

aAction = DoSomething;
aAction += DoAnotherting;

// execute the action -> both functions will be executed
aAction();

aAction -= DoSomething;  // unsubscribe on function

我没有意识到这一点,认为使用+ =只能用于事件。在第一时间,这看起来很好,因为我不必使用event关键字,我也可以从所有者类之外调用此操作(事件不可能)。 但是我想知道,这种用途有什么好的例子,还是只是不好的做法?

此处显示了一个完整的示例:

[TestMethod]
public void DummyTest()
{
    DummyClass myInstance = new DummyClass();

    int i = 0;

    Action action1 = () => i++;
    Action action2 = () => i += 2;

    Func<int> func1 = () => 5;

    myInstance.MyFunc += () => 3;
    myInstance.MyFunc += func1;

    Assert.AreEqual(5, myInstance.MyFunc?.Invoke() );

    myInstance.MyFunc -= func1;

    Assert.AreEqual(3, myInstance.MyFunc?.Invoke() );

    myInstance.MyAction = action1;
    myInstance.MyAction += action2;

    myInstance.MyAction?.Invoke();

    Assert.AreEqual(3, i);
    myInstance.MyAction -= action1;

    myInstance.MyAction?.Invoke();

    Assert.AreEqual(5, i);

    myInstance.MyAction = () => i = 0;

    myInstance.MyAction?.Invoke();

    Assert.AreEqual(0, i);
}


class DummyClass
{
    public Action MyAction;
    public Func<int> MyFunc;
}

1 个答案:

答案 0 :(得分:1)

我的印象是event s的重点是将事件控制置于封闭类型中。事件被触发时,客户无法选择。事件是一个(集合)函数,当某个类型中的某个状态发生更改时,或者当客户端可能想要响应的某些有趣的事情发生时调用(/),但确切的细节应保持隐藏状态。同样的原因是你不应该向客户公开字段。

从某种意义上来说它没有任何内容可以让你感到非常可怕,但是另一方面没有理由像这样使用它们。事件在语言中是有原因的,它们具有语义含义。如果您使用Action / Func代表而不是事件,那么阅读您的代码的人将不得不弄清楚您正在做什么以及为什么您不使用传统工具代替。它只是杂乱/噪音,所以我的建议是避免它。