为什么Action / Func比.Net中的常规方法更好?

时间:2011-12-09 17:56:23

标签: c# .net action func

如果我需要快速可重复使用的代码,我更喜欢使用Action或Func,但是我团队中的其他人不喜欢它们或理解它们。
目前,我唯一真正的论点是关于偏好和更新的代码实践,但这些只是不好的论点。

为什么这样做更好:

Action<FormView,String> hideControl = (form,name) => {
    var button = form.GetControl<Button>(name);
    if (button != null)
        button.Visible = false;
}

比:

public static void HideControl<T>(this FormView form, string name) where T : Control
{
    var button = form.GetControl<Button>(name);
    if (button != null)
        button.Visible = false;
}

任何人都可以给我具体的具体论据/例子吗?

5 个答案:

答案 0 :(得分:30)

你的问题有两个方面:风格和表现。

对于代码风格,使用委托使事情变得有点混乱。没有与代码体相关联的函数名(匿名方法),推断了参数类型,并且当过度使用时,这可能导致在委托中包含许多较小的独立代码块的大型功能块。看起来并不漂亮,很难弄清楚代码实际上在做什么,而且很难找到你想要的东西。

对于性能,委托引入了一个间接,它的执行速度不如普通的旧方法。差异很小,但是当过度使用时,它会变得明显。

任何工具都有适当和过多的用途。当您想要将回调例程传递给函数时,使用Action或Func作为回调参数是合适的。使用Action或Func作为声明函数的替代是一种误用,IMO。

答案 1 :(得分:17)

简短的回答是,一般而言,它并不是更好。我同意你的队友。

我不认为你的问题是正确的。而不是问为什么它更好(相信我不是在大多数情况下),你可能会问它什么时候更好。

现在,有些时候它们非常有用,比如在LINQ中,当方法接受Func时,写一个快速的lambda很棒。

这更具可读性和可维护性:

var myQuery = Customers.Where(x => x.ID == 3).First();

比替代方案:

public bool FilterByID3(Customer cust)
{
  return cust.ID == 3;
}

    var myQuery = Customers.Where(FilterByID3).First();

在大多数其他情况下,使用函数更具可读性/可维护性。

答案 2 :(得分:9)

  

为什么这样做更好

不是更好。在这种情况下,我认为这样做没有任何优势,而不是写一个真正的方法。如果你不能,我也不明白你为什么这么好肯定。

避免编写长匿名方法(总而言之,我的意思是超过一两行),它只会使代码的可读性降低。

但是在某些情况下,使用匿名方法会很有用:闭包。如果您需要捕获局部变量,那么匿名方法就是您的选择。但即便如此,也不要在其中编写一长段代码:只需调用一个将捕获的变量作为参数传递给它的实际方法。

答案 3 :(得分:8)

总的来说,我同意其他的回答者:盲目地用Action / Func替换函数定义并不是一件好事。 ActionFunc不是 .NET的未来。它们是 工具,非常有用,但任何工具都可能被滥用。

所以,如果你倾向于编写像这样的代码

class SomeClass {
    Action<...> a1 = (..) => {};
    Func<...> f1 = (..) => {};
    Action<...> a2 = (..) => {};
    ...
}

这当然不是一件好事。

如果你这么做了:

  void SomeMethod()
  {
      Action<..> a = (..) => {};
      ...
      a();
  }

那么这实际上是一种封装小帮助方法而不会污染类的好方法。

争辩你的具体案例: 如果hideControl仅用于非常特殊的情况,则首选私有帮助方法。如果很多FormViews需要它,那么扩展方法更有意义。扩展方法也是一种可以被滥用的工具,因为它可能导致类的公共接口的污染。虽然您可以通过使用命名空间来限制它。

我通常遵循这条准则: 如果您需要一个在很多地方和情况下都很有用的辅助方法,并且可以使其相当通用,我会创建一个扩展方法。 如果它是特定类所需的辅助方法,但在该类的几个地方(方法)中,那么我创建一个私有方法。 如果它是一个我只需要在一个特定位置的帮助器,那么我在该方法中使它成为一个Action / Func。

答案 4 :(得分:7)

优点

  • 瓶盖
    • 但这对你的情况没有帮助。
  • 超私有方法 - 只有定义方法才能调用它。
    • 虽然单一责任原则可以很容易地解决这个问题。您可能会在整个方法中组合应该是不同的类。
  • 回调
    • 这些也很容易成为方法。

缺点

  • 在我看来,由于压痕过多(我不是粉丝),可读性有所降低。
  • 调试变得有点困难,因为您的调用堆栈不太直观,尤其是当您定义了多个Func / Action时。

你必须在你的环境中克服缺点。

我对你的“更新的编码实践”论点感到好奇。仅仅因为你可以尽可能地做到这一点并不意味着你应该