4 votes

Est-il possible de définir "this" dans une fonction anonyme ?

J'ai une fonction,

public SharpQuery Each(Action<int, HtmlNode> function)
{
    for (int i = 0; i < _context.Count; ++i)
        function(i, _context[i]);
    return this;
}

qui appelle la fonction transmise pour chaque élément du contexte. Est-il possible de définir ce à quoi "ceci" fait référence à l'intérieur de la fonction Action<int, HtmlNode> function ?

Par exemple,

sharpQuery.Each((i, node) => /* `this` refers to an HtmlNode here */);

5voto

Jeff Mercado Points 42075

En modifiant légèrement la fonction, vous pouvez obtenir l'effet souhaité.

public SharpQuery Each(Action<MyObject, int, HtmlNode> function)
{
    for (int i = 0; i < _context.Count; ++i)
        function(this, i, _context[i]);
    return this;
}

Vous pourriez alors écrire votre appel de fonction comme suit :

sharpQuery.Each((self, i, node) => /* do something with `self` which is "this" */);

Note : La fonction anonyme n'aura cependant accès qu'aux membres publics. Si la fonction anonyme a été définie dans la classe, elle aura accès aux membres protégés et privés comme d'habitude.

par exemple,

class MyObject
{
    public MyObject(int i)
    {
        this.Number = i;
    }

    public int Number { get; private set; }
    private int NumberPlus { get { return Number + 1; } }

    public void DoAction(Action<MyObject> action)
    {
        action(this);
    }

    public void PrintNumberPlus()
    {
        DoAction(self => Console.WriteLine(self.NumberPlus));  // has access to private `NumberPlus`
    }
}

MyObject obj = new MyObject(20);
obj.DoAction(self => Console.WriteLine(self.Number));     // ok
obj.PrintNumberPlus();                                    // ok
obj.DoAction(self => Console.WriteLine(self.NumberPlus)); // error

1voto

Non.

Eh bien, oui, si l'action a été créée dans un champ d'application où 'this' était disponible et lié à une fermeture - mais de manière transparente : non.

Transmettez toutes les informations nécessaires ou assurez-vous qu'elles sont saisies/disponibles dans l'action elle-même. Il existe d'autres astuces comme les thread-locals, etc. Il vaut mieux les éviter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X