如果我需要快速可重复使用的代码,我更喜欢使用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;
}
任何人都可以给我具体的具体论据/例子吗?
答案 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
替换函数定义并不是一件好事。 Action
和Func
不是 .NET的未来。它们是 工具,非常有用,但任何工具都可能被滥用。
所以,如果你倾向于编写像这样的代码
class SomeClass {
Action<...> a1 = (..) => {};
Func<...> f1 = (..) => {};
Action<...> a2 = (..) => {};
...
}
这当然不是一件好事。
如果你这么做了:
void SomeMethod()
{
Action<..> a = (..) => {};
...
a();
}
那么这实际上是一种封装小帮助方法而不会污染类的好方法。
争辩你的具体案例:
如果hideControl
仅用于非常特殊的情况,则首选私有帮助方法。如果很多FormViews
需要它,那么扩展方法更有意义。扩展方法也是一种可以被滥用的工具,因为它可能导致类的公共接口的污染。虽然您可以通过使用命名空间来限制它。
我通常遵循这条准则: 如果您需要一个在很多地方和情况下都很有用的辅助方法,并且可以使其相当通用,我会创建一个扩展方法。 如果它是特定类所需的辅助方法,但在该类的几个地方(方法)中,那么我创建一个私有方法。 如果它是一个我只需要在一个特定位置的帮助器,那么我在该方法中使它成为一个Action / Func。
答案 4 :(得分:7)
优点
缺点
Func
/ Action
时。你必须在你的环境中克服缺点。
我对你的“更新的编码实践”论点感到好奇。仅仅因为你可以尽可能地做到这一点并不意味着你应该。