3
votes

Pourquoi puis-je accéder aux propriétés privées lors de l'utilisation de paramètres de constructeur dans la même classe

J'ai un exemple de code fonctionnel et je ne peux pas expliquer pourquoi cela fonctionne comme ça.

Prenons cette classe par exemple.

static void Main(string[] args)
    {

        new TestClass() { _testValue = 23 }; // Does not compile and I am happy with that.

        // The code provided will print ‘Hello World’ to the console.
        // Press Ctrl+F5 (or go to Debug > Start Without Debugging) to run your app.
        Console.WriteLine("Hello World!");
        Console.ReadKey();

        // Go to http://aka.ms/dotnet-get-started-console to continue learning how to build a console app! 
    }

Pourquoi est-ce autorisé ? Je me serais attendu à avoir le comportement suivant:

 public class TestClass
{
    private int _testValue;


    public void TestMethod()
    {
        var t = new TestClass() {_testValue = 42}; // Why is that working?
    }
}

Edit: Merci pour vos commentaires, mais je sais ce que signifie le mot-clé privé, la question est, pourquoi puis-je avoir accès aux propriétés privées lorsque j'utilise un constructeur de paramètres lorsque je suis à l'intérieur du même objet. Placez un débogueur, vous verrez que la TestClass this._testValue n'est pas la même que la t._testValue

Le comportement normal dans mon esprit est celui que j'ai dans la fonction Main.

 Debugger.

c#

9 commentaires

À quelle classe appartient Main ? S'il est différent de TestClass , vous ne pouvez sûrement pas accéder aux membres privés de TestClass . Cependant, dans le TestMethod , vous le pouvez sûrement. C'est ta question? Pourquoi une méthode dans TestClass peut-elle accéder aux membres privés de TestClass ?


Vous êtes autorisé à accéder aux membres de la classe private depuis les membres de la classe. TestMethod est membre de TestClass , vous êtes donc autorisé à accéder à tous les membres private à partir de cette méthode.


"this._testValue n'est pas la même chose que la t._testValue" Bien sûr, parce que vous créez une nouvelle TestClass -instance dans TestMethod , qui n'a rien à voir avec l'instance actuelle ( ceci ). Vous attendez-vous à ce que this pointe vers la même instance que t ?


Mais pourquoi this._testValue serait-il égal à t._testValue ? Ce sont des instances différentes, donc bien sûr leurs valeurs ne sont pas les mêmes (sauf si vous les définissez sur la même valeur).


Honnêtement, c'est quelque chose que je n'ai jamais su (ou même envisagé). TIL. Y a-t-il des cas d'utilisation pratiques pour cela ou n'y avait-il pas l'intention explicite de permettre cela?


C'est privé pour la classe et non pour l'instance. C'est vraiment bizarre de tomber pour la première fois :)


Est-ce que la syntaxe est exactement privée, est-ce que je crée deux objets DIFFÉRENTS, une nouvelle référence, pourquoi puis-je accéder à la propriété privée dans ce cas? Cela m'est vraiment étrange.


Mais le privé ne se soucie pas de l'instance réelle. Il existe deux instances dans deux valeurs totalement indépendantes. Vous pouvez bien sûr examiner les deux, car vous faites partie de cette classe.


Si vous comprenez ce qu'il fait ici, quelle est vraiment la question? Cela fonctionne comme ça parce que quelqu'un a décidé que cela devrait fonctionner comme ça. private signifie privé pour la classe, pas pour l'instance.


4 Réponses :


1
votes

Tiré de la documentation : < / p>

L'accès privé est le niveau d'accès le moins permissif. Membres privés sont accessibles uniquement dans le corps de la classe ou de la structure dans dont ils sont déclarés, comme dans cet exemple:

-snip-

Les types imbriqués dans le même corps peuvent également accéder à ces membres privés.

C'est une erreur de compilation de référencer un membre privé en dehors du class ou la structure dans laquelle il est déclaré.

Quant à votre capture d'écran .. La valeur du premier _testValue est à 0 car c'est la valeur par défaut de int et vous n'avez rien défini d'autre lorsque vous avez créé cet objet.

Le nouvel objet que vous avez créé dans TestClass - vous définissez explicitement une valeur de 23 à cela et vous le faites parce que vous avez accès à cette propriété selon la définition du mot clé privé .


6 commentaires

Je pense que vous faites parce que cela répond à votre question qui, comme vous l'avez dit, est: "pourquoi puis-je avoir accès aux propriétés privées lorsque j'utilise un constructeur de paramètres alors que je suis à l'intérieur du même objet. "


@pix Mais la définition du mot-clé private répond à votre question.


@pix Si la modification ne répond pas à votre question, je pense que votre question ne reflète pas ce que vous pensez qu'elle devrait.


C'est un comportement vraiment étrange, c'est un autre exemple. Pourquoi Microsoft ou l'appeler comme vous voulez, autoriser ce comportement?


@pix Il indique la raison dans la définition :)


@pix Ce "comportement étrange" est, je crois, commun à de nombreux, sinon à tous les langages de programmation qui ont des mots-clés public et private .



3
votes

mot clé privé
L'accès privé est le niveau d'accès le moins permissif. Les membres privés ne sont accessibles que dans le corps de la classe ou de la structure dans laquelle ils sont déclarés ...
Faire référence à un membre privé en dehors de la classe ou de la structure dans laquelle il est déclaré est une erreur de compilation.

Si vous regardez la documentation du mot-clé private , la partie "clé" par rapport à votre question est qu'il est accessible dans le corps de la classe et n'est pas limité à l'accès uniquement par le même instance dans laquelle le membre privé ou la méthode est déclaré.

Dans votre exemple ajouté, TestMethod est dans TestClass , donc le code dans TestMethod peut accéder à toutes les méthodes ou propriétés privées dans sa propre instance et toute autre instance à laquelle il a accès.

Ceci est indiqué dans la définition citée du mot-clé: TestMethod est "dans le corps de la classe dans laquelle _testValue est déclaré", donc il peut y accéder.

Il n'y a aucune restriction dans la documentation selon laquelle l'accès doit se faire via une instance spécifique, donc peu importe comment vous créez ou avez accès à une TestClass nouvelle ou différente à l'intérieur de TestMethod , vous avez accès aux membres privés et aux méthodes de cette instance.

L'une des raisons pour lesquelles nous avons private est de garder les internes à l'écart du code non lié, mais de toujours fournir l'accès à la classe à laquelle il appartient. Cela permet à la classe de manipuler des instances d'elle-même, ce qui est extrêmement important pour copier des données internes d'une instance d'un objet à une autre. Vous ne voulez pas rendre ces publics , car alors tout autre code sans rapport aurait un accès indésirable.

Ce comportement de private est au moins partagé avec C ++ et TypeScript, et il est probablement commun dans la plupart sinon tous les langages de programmation qui ont public et private < / code> accès.


3 commentaires

Je suis désolé de ne pas voir en quoi c'est une réponse à ma question, je viens d'ajouter un écran de débogage.


@pix: La réponse est claire: il est accessible dans le corps de la classe et n'est pas limité à l'accès uniquement par la même instance .


@pix J'ai essayé d'ajouter des explications supplémentaires concernant l'exemple que vous montrez, mais la clé se trouve dans la définition qui se rapporte à "dans le corps de la classe" et non "dans la même instance d'une classe".



0
votes

Permettez-moi de me référer à cette partie spécifique de votre question - je pense que cela devrait vous aider à comprendre le comportement:

Placez un débogueur, vous verrez que la TestClass this._testValue n'est pas la même que la t._testValue

Maintenant, quelques éclaircissements sur toutes ces définitions de mots clés privé que les gens ont publiées ici. Les modificateurs d'accès private et protected font référence à une classe et non à un objet - cela signifie que si une propriété est marquée en tant que private , alors tout objet de cette classe peut accéder à cette propriété privée dans n'importe quelle instance de la même classe, y compris différents objets. C'est pourquoi la définition dit spécifiquement:

Les membres privés ne sont accessibles que dans le corps de la classe ou de la structure dans laquelle ils sont déclarés.

C'est la même chose si la plupart (sinon tous) des langages de programmation orientés objet. La justification pourrait être que si deux objets appartiennent à la même classe, alors ils savent comment gérer et utiliser correctement et en toute sécurité leurs membres privés - il est alors inutile de restreindre cet accès.


0 commentaires

0
votes

Vous semblez supposer que private se soucie de l ' instance - ce qui n'est évidemment pas le cas. En fait, vous n'avez même pas besoin d'une instance - par ex. sur un membre statique .

Donc, si vous pouvez accéder ou non à un membre d'une classe dépend de deux facteurs:

  1. Êtes-vous dans le même périmètre que ce membre?
  2. avez-vous accès à l'instance à laquelle appartient le membre?

Dans votre cas, votre membre est privé , ce qui fait que les membres portent le niveau de classe. TestMethod est une méthode au sein de cette classe, donc le point 1 correspond.

Vous avez deux instances différentes. Comme vous êtes dans TestMethod , vous pouvez bien sûr accéder aux membres de this (l'instance actuelle). De plus, vous avez une référence à l'instance nouvellement créée t . Le point 2 s'applique donc également et vous pouvez accéder aux deux membres des deux instances.

En passant au point 2: si le membre est statique, il n'y a pas d'instance, vous pouvez toujours y accéder depuis une autre instance.


0 commentaires