web-dev-qa-db-fra.com

Les méthodes d'extension C # peuvent-elles accéder aux variables privées?

Est-il possible d'accéder aux variables privées d'un objet à l'aide d'une méthode d'extension?

67
Geo

Non. Vous pouvez faire la même chose dans une méthode d'extension que dans une méthode statique "normale" dans certaines classes d'utilitaires.

Donc, cette méthode d'extension

public static void SomeMethod(this string s)
{
    // do something with 's'
}

est équivalent à une méthode d'assistance statique comme celle-ci (au moins en ce qui concerne ce à quoi vous pouvez accéder):

public static void SomeStringMethod(string s)
{
    // do something with 's'
}

(Bien sûr, vous pouvez utiliser une réflexion dans l'une ou l'autre méthode pour accéder aux membres privés. Mais je suppose que ce n'est pas le but de cette question.)

71
M4N

Non ça ne peut pas.

Cependant, vous serez intéressé de savoir que les autres réponses sont incorrectes en disant que les méthodes statiques normales ne peuvent pas accéder aux champs privés. Une méthode statique peut accéder aux champs membres non statiques privés dans sa propre classe. Le code suivant est parfaitement valide et montre une méthode statique accédant à un champ privé:

public class Foo
{
    private bool _field;

    public static bool GetField(Foo foo)
    {
        return foo._field;
    }
}

Maintenant ... revenons à votre question. Vous pourriez penser qu'une méthode d'extension devrait être capable de faire la même chose, étant donné "l'équivalence" (inexistante) aux méthodes statiques qui, selon d'autres réponses, existent. Cependant, vous ne pouvez pas déclarer de méthodes d'extension dans une classe imbriquée. Donc, si vous essayez de faire ce qui suit:

public class Foo
{
    private bool _field;

    public static class Extensions
    {
        public static bool GetField(this Foo foo)
        {
            return foo._field;
        }
    }
}

Vous obtiendrez une erreur de compilation disant

La méthode d'extension doit être définie dans une classe statique de niveau supérieur; Les extensions sont une classe imbriquée

Notez que, chose intéressante, la suppression du mot clé this entraîne une compilation correcte du code. Les raisons de ceci sont discutées ici:

  1. Pourquoi les méthodes d'extension ne sont-elles autorisées que dans une classe statique non imbriquée et non générique?
  2. Pourquoi ne pas autoriser la définition de la méthode d'extension dans une classe imbriquée?
23
Zaid Masud

Non:

public class Foo
{
    private string bar;
}

public static class FooExtensions
{
    public static void Test(this Foo foo)
    {
        // Compile error here: Foo.bar is inaccessible due to its protection level  
        var bar = foo.bar;
    }
}
11
Darin Dimitrov

Non, sauf si vous leur donnez un accès quelconque via des propriétés publiques ou un modèle de proxy.

3
Yuriy Faktorovich

Utiliser la réflexion

Non recommandé, mais vous pouvez éventuellement accéder à n'importe quelle variable privée de tout type en utilisant une autre méthode d'extension comme ceci:

public static T GetFieldValue<T>(this object obj, string name) {
    var field = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    return (T)field?.GetValue(obj);
}

Et puis accédez à un champ privé de type arbitraire:

Foo foo = new Foo();
string privateBar = foo.GetFieldValue<string>("_bar");
2
Bruno Zell

Si vous possédez la classe que vous étendez, vous pouvez toujours déclarer la classe partielle, puis étendre la classe et avoir accès à tous les membres privés dans un fichier différent ... Mais vous n'utiliseriez pas vraiment les méthodes d'extension.

2
Rimbimbambo

Une méthode d'extension est essentiellement une méthode statique, vous n'avez donc accès qu'aux membres publics de l'instance sur laquelle la méthode d'extension est invoquée.

0
Abhijeet Patel