私有方法与本地函数

Sip*_*ipo 9 c# c#-7.0

据我了解,本地函数和私有方法都只是作为实现细节——公共方法的助手。为什么我要选择一个而不是另一个?

使用私有方法时,我在对象和方法之间创建了语义关系(虽然从外面看不到),这并不总是合理的。这就是为什么我的第一直觉是本地函数是可行的方法,除非有多个公共方法使用它,在这种情况下我会使用私有方法。

但是,是否有任何客观的理由来支持其中之一?有没有一种情况比另一种更可取的情况?使用其中任何一个的优缺点是什么?

Ral*_*ing 11

这都是关于代码可读性的。查看局部函数的动机

局部函数使您的代码意图清晰。任何阅读您代码的人都可以看到,除了包含方法之外,该方法是不可调用的。对于团队项目,它们还使其他开发人员无法直接从类或结构的其他地方错误地调用该方法。

局部函数的主要原因是为了给意图:这段代码只针对这个方法;不要从其他地方重复使用它。另有说明:私有方法表明它们可能从其他类方法中重用。

此处的 Roslyn-Rep 中讨论了此语言功能背后的更多用例。:

  • 编写一个只在一个地方使用的辅助方法是很常见的,但它使代码对读者不太清楚,因为辅助函数与其所帮助的事物之间的关联并不明确。局部函数使关联成为语法的一部分。
  • 一个验证其参数的迭代器方法(编写一个非迭代器函数来验证参数,然后返回调用本地迭代器函数的结果)
  • 在不需要“异步”的常见情况下没有异步机制的任务返回方法
  • 您正在编写一个返回数组的方法,但需要迭代器方法语法(yield return)的语法便利。

这些用例在博客文章中进行了解释https://devblogs.microsoft.com/premier-developer/dissecting-the-local-functions-in-c-7/


Aka*_*ava 5

有时逻辑是巨大的并且包含许多重复,例如......

public void ValidateCustomer(Customer customer){

  if( string.IsNullOrEmpty( customer.FirstName )){
       string error = "Firstname cannot be empty";
       customer.ValidationErrors.Add(error);
       ErrorLogger.Log(error);
       throw new ValidationError(error);
  }

  if( string.IsNullOrEmpty( customer.LastName )){
       string error = "Lastname cannot be empty";
       customer.ValidationErrors.Add(error);
       ErrorLogger.Log(error);
       throw new ValidationError(error);
  }

  ... on  and on... 
}
Run Code Online (Sandbox Code Playgroud)

这种重复可以用局部函数代替,

  public void ValidateCustomer(Customer customer){

      void _validate(string value, string error){
           if(!string.IsNullOrWhitespace(value)){

              // i can easily reference customer here
              customer.ValidationErrors.Add(error);

              ErrorLogger.Log(error);
              throw new ValidationError(error);                   
           }
      }

      _validate(customer.FirstName, "Firstname cannot be empty");
      _validate(customer.LastName, "Lastname cannot be empty");
      ... on  and on... 
  }
Run Code Online (Sandbox Code Playgroud)

如果仔细观察,您不必将参数传递给本地函数,因为它们可以引用封闭函数中的所有内容,您只需传递更改的参数。如果您编写私有方法,则必须传递许多参数。