Est-il possible d'accéder aux variables privées d'un objet à l'aide d'une méthode d'extension?
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.)
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:
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;
}
}
Non, sauf si vous leur donnez un accès quelconque via des propriétés publiques ou un modèle de proxy.
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");
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.
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.