C#中的事件或Lambda?

时间:2009-04-27 20:41:28

标签: c# events lambda

我把它扔出去只是为了好奇心问题......

假设您只是期望/想要提供一种方法,这会不赞成或不良做法?

public class Something  {
    public Action OnRemove = () => { };
    public Action<object, EventArgs> OnFinishedLoading = (sender, e) => { };
}

// then used like...
something.OnRemove = () => { /*do something...*/ };
something.OnFinishedLoading = (sender, e) => { /*do something else...*/ };

我意识到这就像在事件中作弊一样,但我对这种方法有什么不好的意思吗?从长远来看,这是否会导致您的应用程序出现任何潜在问题?

我意识到如果你想要运行多个方法,那么事件会更好,这主要是一个问题,你是否只想要/期待一种方法。

5 个答案:

答案 0 :(得分:6)

嗯,最明显的“错误”是它揭露了公共领域。我至少使用了一个属性 - 此时事件可能会更简单。它使用比属性更少的代码提供更大的灵活性(因为您无法使用具有特定默认值的自动实现的属性)。

另一种选择是将它放在构造函数中,然后将其保存为私有只读字段。这可能是我真正倾向于做的事情......是否真的需要将行动作为财产/领域公开?

答案 1 :(得分:1)

这种方法没有任何问题,我经常使用它。它使简单的处理程序具有简单的代码(这是一件好事)。

这种方法的唯一缺点是无法轻易删除以这种方式创建的处理程序。通常你会说

something.OnRemove -= SomeEvent;

但是所有lambda表达式都不是这种情况。文本上相等的lambda表达式几乎肯定会有单独的实现,因此不会匹配添加和删除事件处理程序的目的。

例如,以下代码将无法删除处理程序。

something.OnRemove += () { MessageBox.Show("Removed!"); }
something.OnRemove -= () { MessageBox.Show("Removed!"); }

但只要您只想添加,这不是问题。

答案 2 :(得分:1)

它可能会暴露出比你想要的更多。通常,事件不允许客户端检查支持事件的MulticastDelegate的内容。

答案 3 :(得分:1)

我认为这种方法很好,它只是一种声明委托的简便方法(查看Action系列的定义)。

答案 4 :(得分:0)

通过此活动,您无法执行此操作:

something.OnRemove = null;

事件为您提供了一个包装器,一种包含属性和属性的包装器,因此您可以确保通过Delegate方法进行封装。