C# 如果只使用一次本地函数,那么使用本地函数有意义吗?

C# 如果只使用一次本地函数,那么使用本地函数有意义吗?,c#,methods,refactoring,local,c#-7.0,C#,Methods,Refactoring,Local,C# 7.0,假设我有以下代码: public void Foo() { // Do bar work // Do baz work // Do foobar work } 我意识到我可以(而且应该,因为它做的不止一件事)将其重构为: public void Foo() { bar(); baz(); foobar(); } private void bar() { /* do bar work */ } private void baz() {

假设我有以下代码:

public void Foo()
{
    // Do bar work
    // Do baz work
    // Do foobar work
}
我意识到我可以(而且应该,因为它做的不止一件事)将其重构为:

public void Foo()
{
    bar();
    baz();
    foobar();
}

private void bar()    { /* do bar work */ }
private void baz()    { /* do baz work */ }
private void foobar() { /* do foobar work */ }
但后来我意识到,我永远不会在
Foo()
之外使用这些函数,因此这些函数只会使主页和自动完成变得杂乱无章。我可以这样做:

public void Foo()
{
    bar();
    baz();
    foobar();

    void bar()    { /* do bar work */ }
    void baz()    { /* do baz work */ }
    void foobar() { /* do foobar work */ }
}

这将使事情更整洁,更少混乱,但我现在真正做的是使方法更长,而不是更短

使用匿名函数:

public void Foo()
{
    Action bar = delegate () { /* do bar work */ };
    Action baz = delegate () { /* do baz work */ };
    Action foobar = delegate () { /* do foobar work */ };

    bar();
    baz();
    foobar();
}
或lambda表达式语法:

public void Foo()
{
    Action bar = () => { /* do bar work */ };
    Action baz = () => { /* do baz work */ };
    Action foobar = () => { /* do foobar work */ };

    bar();
    baz();
    foobar();
}

我非常喜欢@Mark Benningfield使用部分文件的想法(当我的类太大并且有一两个uber方法时,我会这么做)


我对局部函数的唯一问题是,它们可以捕获变量,并且并不总是清楚函数是否这样做。因此,通过将“real”方法“升级”为“local”,您就扩大了它的可见性。

本地函数比匿名函数具有优势,因为匿名函数只能通过委托调用,而委托调用除了为委托分配内存外,成本更高

局部函数可以是递归函数,而无需代理所需的技巧:

int f(int i) => i >= 1 ? i * f(i - 1) : 1;

Func<int,int> d = null;
d = (int i) => i >= 1 ? i * d(i - 1) : 1;
intf(inti)=>i>=1?i*f(i-1):1;
Func d=null;
d=(int i)=>i>=1?i*d(i-1):1;
与匿名委托一样,与顶级方法不同,局部函数可以捕获局部变量。而且由于它们是本地的,所以其他函数无法调用它们

这将使事情更整洁,更少混乱,但我现在真正做的是使方法更长,而不是更短

不,你没有。你基本上是在说,一个类有一个方法可以做很多事情,而另一个类做同样的工作,但是有多个更短、更容易维护的方法,两者之间没有任何区别


您的局部函数就像方法一样,它们包含在另一个方法中这一事实并不排除整体更易于维护;功能封装在明确定义的范围内。

它可以帮助您提高可读性和可维护性,但这取决于方法。它们是包含很多代码还是只有几行?我想这取决于可读性。如果留在主函数上,bar()、baz()和foobar()会吐出多少代码。此外,它们是否有足够的相关性,以至于可以放在main上?如果代码组织是唯一的难点,只需将它们自己粘贴到部分类文件中即可。此外,您可以命名私有助手方法,这样它们就不会直接跳到“自动完成”的顶部。@SebastianOfmann所讨论的方法只有11行。您的本地函数版本似乎很好,它可以将内容保持在最小的必要范围内,同时仍然放置(我猜)代码块的有用名称。与问题中所示的版本相比,这没有优势,缺点是更长。这实际上是一样的,只是我必须在代码的顶部声明匿名函数。我喜欢在所有东西下面都有本地函数,包括返回语句。我发现它更容易阅读。此外,使用委托会带来性能成本,因为它必须分配内存来创建delagate,但如果我不打算将该委托传递给其他对象(我不打算),那就是浪费内存。本地函数不必为自己分配任何内存,而且它们有更好的语法。你说得对!我误解了这个问题。我不知道C#7.0中的局部函数,但现在我明白了。我想也许你想要一种实现这种行为的方法。对,但有时候捕获变量就是我想要的行为。我很喜欢局部函数能够直接使用父函数的参数或局部变量,而不必将它们作为参数传递。@AustinWBryan捕获变量没有问题。。。只是我更喜欢本地函数使用这个特性,其他函数显然不使用。所以我用这个(捕获/不捕获)作为分界线。但这是一条在沙子上画的线。我明白了,这是一条聪明的经验法则