C#:Func<>而不是方法?
对于所有了解这一点的人来说,这是一个好奇的问题:
使用 Func 而不是方法有什么坏处/缺点吗?简单的例子:
private static Func<int, int, DBContext, List<T>> Foo =
(i1, i2, dbc) =>
(i1 != 0) ? dbc.Bar(i2) : new List<T> { /*some default values ...*/ };
Vs
private static List<T> Foo(int i1, int i2, DBContext dbc)
{
return i1 != 0 ? dbc.Bar(i2) : new List<T> { /*some default values ...*/ };
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我看到了几个缺点:
因为你什么也得不到 我只会在本地和小上下文,更喜欢静态方法
I see severale downsides:
as you gain nothing I would only to so in a local and small context and prefer the static method
性能并不像最初看起来那么重要,调用委托和通过 v_table 分派的方法(虚拟实例方法)的成本是相当的。在这种情况下,对于静态方法,不使用委托可能会带来较小的性能提升。
您在这里发现的“技巧”是一种相当常见的技术,无需借助面向对象的编程技术(例如策略模式)即可实现功能分解。您可以将方法调用替换为对委托的调用。这个技巧的另一个好处是调用的语法是相同的。
然而,我会非常小心地应用这种技术。我通常使用它的目的是避免使用单一方法的接口,该方法不具有超过一两个参数(否则我会考虑使用参数对象或使用接口)。
C# 是一种多范式语言,每种范式都有其用途。函数范式(例如使用 Func 代替编译时已知方法)有其一席之地,面向对象范式也是如此。在您的情况下,使用
Func<>
没有任何好处,为了清楚起见,您应该使用传统方法。Performance is not as much of an argument as it would seem originally, the cost of invoking a delegate and a method that is dispatched through the
v_table
(virtual instance methods) are comparable. In this case, for a static Method it is likely there is a small performance gain for not using the delegate.The "trick" you discovered here is a fairly common technique to achieve functional decomposition without resorting to object-oriented programming techniques (e.g. the Strategy Pattern). You replace a method call with a call to a delegate. Another nice aspect of this trick is that the syntax for invocation is the same.
However, I would be extremely careful applying this technique. What I do usually use it for is to avoid Interfaces with a single method, that do not have more than one or two parameters (else I would consider using a Parameter Object or using an interface).
C# is a multi-paradigm language, and using each paradigm has its place. Functional paradigms (such as using Funcs instead of compile-time known methods) have their place, as do object oriented paradigms. In your case, there is no benefit over using a
Func<>
, you should use a traditional method for clarity instead.在第一种情况(使用 Func)中,您不是编写方法,而是编写使用特定委托初始化的变量 Foo。您可以使用一级间接来更改 Foo 指向的内容。为了简化您的示例:
让我们测试一下:
因此,如果您使用这种间接级别,则 Func 方法是有意义的。但是,如果您不使用它,则说明您引入了过多的间接级别,这会影响性能、代码传达其意图的程度以及程序的正确性(因为您的方法现在可以切换为另一种方法)在运行时做一些不同的事情)
In the first case (with Func), you're not writing a method, but a variable Foo that you initialize with a specific delegate. You have one level of indirection that you can use to change what Foo points to. To simplify your example:
let's test:
so, if you are usign this level of indirection, the Func approach makes sense. But if you're not using it, you have introduced one level of indirection too many, with impact on performance, on how well your code communicates its intent and on the correctness of your program (since your method can now be switched for another that does something different at runtime)
理想情况下,如果总是只有一个 Func 定义,您就不会想创建一个 Func ..您不必要地增加了代码的复杂性和可读性,从而影响了可维护性..
如果您有充分的理由像您创建的那样使用它基于某些条件动态地调用 Func,然后使用 Func<>是有道理的..
另外看看Action。这是我阅读的一篇博客,解释何时使用什么: http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/
ideally you wouldnt wanna create a Func if there is just going to be one definition of it always.. you are unnecessarily increasing the complexity and readability of the code and thus affecting the maintainability..
if you have strong reasons to use it like you create Func dynamically based on certain conditions then using Func<> is justified..
Also take a look at Action. here is a blog that I read to explain when to use what: http://simpleprogrammer.com/2010/09/24/explaining-what-action-and-func-are/
从“学习书”的角度来看,它应该是相同的,但
From the "learning book" perspective it should be the same, but
arg1
,arg2
)除了可读性下降之外,我认为没有任何其他危害。不确定代码如何编译,但在第一个版本中,您只是使用委托定义函数。我想你还可以执行以下操作:
Apart from the readablity downgrade I don't think there's any other harm. Not sure about how the code compiles, but on the first version you are just defining the function using a delegate. I suppose you could also do the following: