C#语言的局部函数
示例
局部函数在方法内定义,在方法外不可用。他们可以访问所有局部变量并支持迭代器,async/await和lambda语法。这样,可以在不使类拥挤的情况下对特定于功能的重复进行功能化。作为副作用,这提高了智能提示功能。
示例
double GetCylinderVolume(double radius, double height) { return getVolume(); double getVolume() { // 您可以在局部函数中声明内部局部函数 double GetCircleArea(double r) =>Math.PI* r * r; // 即使父级没有任何输入,也可以访问所有父级变量。 return GetCircleArea(radius) * height; } }
局部函数极大地简化了LINQ运算符的代码,在LINQ运算符中,通常必须将参数检查与实际逻辑分开,以使参数检查立即生效,直到进行迭代后才延迟。
示例
public static IEnumerable<TSource> Where<TSource>( this IEnumerable<TSource> source, Func<TSource, bool> predicate) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); return iterator(); IEnumerable<TSource> iterator() { foreach (TSource element in source) if (predicate(element)) yield return element; } }
本地函数还支持async和await关键字。
示例
async Task WriteEmailsAsync() { var emailRegex = new Regex(@"(?i)[a-z0-9_.+-]+@[a-z0-9-]+\.[a-z0-9-.]+"); IEnumerable<string> emails1 = await getEmailsFromFileAsync("input1.txt"); IEnumerable<string> emails2 = await getEmailsFromFileAsync("input2.txt"); await writeLinesToFileAsync(emails1.Concat(emails2), "output.txt"); async Task<IEnumerable<string>> getEmailsFromFileAsync(string fileName) { string text; using (StreamReader reader = File.OpenText(fileName)) { text = await reader.ReadToEndAsync(); } return from Match emailMatch in emailRegex.Matches(text) select emailMatch.Value; } async Task writeLinesToFileAsync(IEnumerable<string> lines, string fileName) { using (StreamWriter writer = File.CreateText(fileName)) { foreach (string line in lines) { await writer.WriteLineAsync(line); } } } }
你可能已经注意到一个重要的事情是,当地的功能可以下定义return声明,他们不会需要它上面进行定义。此外,本地函数通常遵循“lowerCamelCase”命名约定,以便更轻松地将自己与类范围函数区分开。