C# Language Fonctions locales


Exemple

Les fonctions locales sont définies dans une méthode et ne sont pas disponibles en dehors de celle-ci. Ils ont accès à toutes les variables locales et prennent en charge les itérateurs, la syntaxe async / await et lambda. De cette façon, les répétitions spécifiques à une fonction peuvent être fonctionnalisées sans surcharger la classe. Comme effet secondaire, cela améliore la performance de la suggestion intellisense.

Exemple

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;
    }
}

Les fonctions locales simplifient considérablement le code pour les opérateurs LINQ, où vous devez généralement séparer les vérifications d’argument de la logique réelle pour que les vérifications d’argument soient instantanées, et ne soient retardées qu’après le démarrage de l’itération.

Exemple

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;
    }
}

Les fonctions locales prennent également en charge l' async et await mots-clés.

Exemple

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);
            }
        }
    }
}

Une chose importante que vous avez peut-être remarquée est que les fonctions locales peuvent être définies dans la déclaration de return , elles ne doivent pas nécessairement être définies au-dessus. De plus, les fonctions locales suivent généralement la convention de dénomination "lowerCamelCase" pour se différencier plus facilement des fonctions de portée de classe.