为什么.net中的动作/函数比常规方法更好?

本文关键字:常规 方法 更好 函数 net 为什么 | 更新日期: 2023-09-27 18:17:27

如果我需要一个快速可重用的代码片段,我更喜欢使用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;
}

?

谁能给我一个坚实的具体的论据/例子?

为什么.net中的动作/函数比常规方法更好?

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

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

为了提高性能,委托引入了一个执行速度不如普通旧方法快的间接方法。差别很小,但如果使用过度,就会变得明显。

任何工具都有适当和过度的使用。当您想要将回调例程传递到函数中时,使用Action或Func作为回调参数是合适的。在我看来,使用Action或function来代替声明函数是一种误用。

简短的回答是,一般来说,它并没有更好。我同意你的队友。

我认为你的问题问得不对。与其问为什么更好(相信我,大多数情况下不是这样),不如问什么时候更好。

当然,有时候它们是非常有用的,比如在LINQ中,当方法接受一个函数时,编写一个快速的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();
在大多数其他情况下,使用函数更具可读性和可维护性。

为什么这样做更好

它没有更好。在这种情况下,我看不出这样做比编写一个真正的方法有什么好处。如果你也不能,我不明白你为什么这么肯定它更好。

避免编写长匿名方法(这里的长是指超过一行或两行),它只会使代码可读性降低。

然而,在某些情况下,使用匿名方法是有用的:闭包。如果您需要捕获一个局部变量,那么匿名方法就是最好的选择。但即使这样,也不要在其中编写一长段代码:只需调用一个真正的方法,将捕获的变量作为参数传递给该方法。

总的来说,我同意其他答案:盲目地用Action/Func代替函数定义不是一件好事。ActionFunc不是。net的未来。它们是一个非常有用的工具,但像任何工具一样可能被滥用。

如果你想写这样的代码

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

这当然不是一件好事。

如果你经常这样做:

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

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

论证你的具体案例:如果hideControl仅在非常特殊的情况下使用,则首选私有助手方法。如果需要大量的FormViews,那么扩展方法更有意义。扩展方法也是一种可能被滥用的工具,因为它可能导致类的公共接口受到污染。尽管您可以通过使用名称空间来限制它。

我通常是这样做的:如果你需要一个在很多地方和情况下都很有用的助手方法,并且可以相当通用,我创建了一个扩展方法。如果它是一个特定类所需的助手方法,但在该类中的几个地方(方法),那么我创建一个私有方法。如果它是一个助手,我只需要在一个特定的地方,然后我把它作为一个Action/Func的方法。

优点


  • 闭包
  • 超私有方法——只有定义方法可以调用它。
    • 这很容易与单一责任原则相抗衡。你很可能在一个完整的方法中组合了一个本应该是不同的类。
  • 回调
    • 这些也可以很容易地作为方法。
    • 可读性降低了,在我看来,因为过多的缩进(我不是一个粉丝)。
    • 调试变得有点困难,因为你的调用堆栈不太直观,特别是当你有多个Func/Action的定义。

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

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