如果只使用一次,使用局部函数有什么意义吗?
Is there any point in using local functions if to only use them once?
假设我有这个代码:
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 使用部分文件的想法(当我的 类 太大并且有一个或两个超级方法时,我就是这样做的)
我对本地函数的唯一问题是它们可以 捕获变量,但并不总是很清楚它们是否正在这样做。因此,通过 "promoting" 一个 "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;
与匿名委托一样,局部函数与顶级方法不同,可以捕获局部变量。而且因为你是本地的,所以它们不能被其他函数调用。
Which would make things neater and less clutter, but all I've really done now is made the method even longer instead of shorter.
不,你没有。您基本上是在说类似的事情,就像 class 与一种完成大量工作的方法与 class 完成相同工作但具有多种更短且更易于维护的方法之间没有任何区别。
你的局部函数就像方法一样,它们包含在另一个方法中这一事实并不排除整体更容易维护;功能封装在明确定义的范围内。
假设我有这个代码:
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 使用部分文件的想法(当我的 类 太大并且有一个或两个超级方法时,我就是这样做的)
我对本地函数的唯一问题是它们可以 捕获变量,但并不总是很清楚它们是否正在这样做。因此,通过 "promoting" 一个 "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;
与匿名委托一样,局部函数与顶级方法不同,可以捕获局部变量。而且因为你是本地的,所以它们不能被其他函数调用。
Which would make things neater and less clutter, but all I've really done now is made the method even longer instead of shorter.
不,你没有。您基本上是在说类似的事情,就像 class 与一种完成大量工作的方法与 class 完成相同工作但具有多种更短且更易于维护的方法之间没有任何区别。
你的局部函数就像方法一样,它们包含在另一个方法中这一事实并不排除整体更容易维护;功能封装在明确定义的范围内。