Looking for c# Keywords? Try Ask4Keywords

C# Language Локальные функции


пример

Локальные функции определяются внутри метода и недоступны вне его. Они имеют доступ ко всем локальным переменным и поддерживают итераторы, синтаксис async / await и лямбда. Таким образом, повторения, специфичные для функции, могут функционировать без перенаселения класса. Как побочный эффект, это улучшает производительность предложения intellisense.

пример

double GetCylinderVolume(double radius, double height)
{
    return getVolume();

    double getVolume()
    {
        // You can declare inner-local functions in a local function 
        double GetCircleArea(double r) => Math.PI * r * r;

        // ALL parents' variables are accessible even though parent doesn't have any input. 
        return GetCircleArea(radius) * height;
    }
}

Локальные функции значительно упрощают код для операторов 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», чтобы более легко отличить себя от функций класса.