C#:为什么可以';我们有内部方法/局部函数吗?

C#:为什么可以';我们有内部方法/局部函数吗?,c#,.net,C#,.net,经常发生的情况是,我有一些私有方法,它们变得非常大,并且包含重复的任务,但是这些任务非常具体,所以让它们对任何其他代码部分都可用是没有意义的 因此,在这种情况下,能够创建“内部方法”将是非常棒的 有没有任何技术(甚至哲学)上的限制阻止C#给出这一点?还是我错过了什么 2016年更新:这即将到来,它被称为“本地函数”。请参阅标记的答案。我们可以在函数中定义“匿名方法”(我不建议使用它们来组织大型方法): 如果某个对象比通常情况下长且复杂,那么最好将其重构为单独的类(正常或静态-取决于上下文)在这里

经常发生的情况是,我有一些私有方法,它们变得非常大,并且包含重复的任务,但是这些任务非常具体,所以让它们对任何其他代码部分都可用是没有意义的

因此,在这种情况下,能够创建“内部方法”将是非常棒的

有没有任何技术(甚至哲学)上的限制阻止C#给出这一点?还是我错过了什么

2016年更新:这即将到来,它被称为“本地函数”。请参阅标记的答案。

我们可以在函数中定义“匿名方法”(我不建议使用它们来组织大型方法):


如果某个对象比通常情况下长且复杂,那么最好将其重构为单独的类(正常或静态-取决于上下文)在这里你可以有专用于这个功能的私有方法。

我知道很多人不喜欢区域,但是这是一个通过将你的特定方法分组到一个区域中来证明有用的例子。

如果你的方法变得太大,考虑把它放在一个单独的类中,或者创建私有助手方法。通常,每当我写评论时,我都会创建一个新方法。

你能给出一个更具体的例子吗?读了你的帖子后,我有以下印象,当然这只是猜测,因为信息有限:

  • 私有方法在类之外不可用,因此它们对任何其他代码都是隐藏的
  • 如果您想对同一类中的其他代码隐藏私有方法,那么您的类可能太大,并且可能违反单一责任规则
  • 看看匿名委托和lambda表达式。这并不完全是你所要求的,但他们可能会解决你的大部分问题

Achim

更好的解决方案是重构此方法以分离类。在初始类中将该类的实例创建为私有字段。将big方法公开,并将big方法重构为几个私有方法,这样就可以清楚地了解它的作用。

似乎我们将通过C#7/Visual Studio 15中的本地函数获得我想要的功能:

真可惜,我为此等了7年多:-)


关于C#的早期版本,请参见其他答案。

有什么比私有方法更内在?方法仅对某个方法可用?这似乎是多多少少。你错过了一些东西。C#从C#2.0开始就有这个功能了。@Eric Lippert:你能提供一些细节吗?谢谢。在C#2及更高版本中,您可以使用匿名方法。在C#3及更高版本中,可以使用lambda表达式。您在下面说过“即使使用Func,我也只能传递一个参数”。Func的一些版本在C#3中使用零、一、二、三和四个参数,在C#4中最多可以使用8个参数。或者,您可以定义自己的委托类型,该类型具有所需的任何参数。“Func”没有什么特别之处。这只是无数可能的委托类型中的一种。@Mehrdad Afshari:看起来很有趣,似乎“Func”可以用于此。但是为什么不使用它们来组织一个大的方法呢?”贾景晖:你应该考虑把一个大的方法分解成几个较小的方法,而不是匿名的方法。首先,正如OP所说,有时子方法只是外部方法的一个实现细节,因此可以用它来封装。第二,这意味着我可以在内部方法中使用外部方法的局部变量,而不必传递它们。@Eric:我假设您是以“函数式语言风格”来完成这项工作的,而不仅仅是将其分解为一个单独的
#区域。这是真的吗?简单地说,是的。我心中有一个例子,但它不适合评论。也许有一天会成为一篇好的博客文章。:-)直到我知道之前,我一直在创建一个私有助手方法,但我通常以太多的私有助手方法结束,以至于过了一段时间,我不知道哪个私有方法使用哪个私有方法。这就是为什么我希望把这些辅助方法包含在需要它们的方法中。@贾景晖,如果方法变得太大了,也许是时候考虑创建一个新类了,但是很难说什么是“正确的”。方法是不知道代码。这是我已经做的:-)我经常使用区域和分部类。我同意lambda表达式可以解决我的问题。即使使用Func,我也只能传递1个参数。Mehrdad Afshari回答说,他不会用这个来简化方法。。。
void test() {
   Action t = () => Console.WriteLine("hello world");  // C# 3.0+
   // Action t = delegate { Console.WriteLine("hello world"); }; // C# 2.0+
   t();
}
private int SomeMethodExposedToObjectMembers(int input)
{
    int InnerMethod(bool b)
    {
        // TODO: Change return based on parameter b
        return 0;
    }

    var calculation = 0;
    // TODO: Some calculations based on input, store result in calculation

    if (calculation > 0) return InnerMethod(true);
    return InnerMethod(false);
}