12
votes

Blocage d'accès aux variables des membres privés? Forcer l'utilisation des propriétés publiques?

J'utilise .NET 2.0 Donc, ne pas avoir accès à des propriétés automatiques. Je dois donc recourir à la manière suivante de coder des variables privées et des propriétés publiques xxx

pour les méthodes de la classe contenant des membres privés / publics ci-dessus, est là pour limiter l'accès à la variable privée ? Je n'aime pas que je puisse utiliser M_Hello ou Bonjour.

Merci.


10 commentaires

Une chose à noter - même si vous ciblez .NET 2.0, si vous utilisez C # 3 pour le faire, vous pouvez toujours utiliser des propriétés automatiques. Ils n'exigent aucun soutien cadre.


@Jon - C'est probablement une information suffisamment importante pour justifier une réponse plutôt qu'un commentaire.


@tvanfosson - Je suis d'accord, je n'avais aucune idée de ça!


Pas très pertinent, mais je suis surpris que les gens utilisent toujours "m_". Non seulement il est recommandé contre (je préfère personnellement une "_" de premier plan pour indiquer des variables privées), c'est aussi laid, bien que cela puisse être un avis personnel. Voici un article sur les conventions et normes de programmation de nommage .net: 10rem.net/articles/...


J'ai posé une question similaire ici: Stackoverflow.com/questions/ 3161401 / ...


J'allais dire la même chose Kevin cependant +1 pour la citant aussi.


@ADAM: Tu m'as taquiné! ;)


@Kevin: Vous devez cependant admettre que c'est l'un des sujets les plus subjectifs que nous pourrions en discuter. Ce n'est pas comme le code d'appel jamais ces noms variables. Une fois que vous avez au moins décidé de distinguer vos députés privés de ceux publics par leur nom, c'est une question d'esthétique personnelle (et d'équipe).


@tvanfosson: dûment ajouté et expansé légèrement.


@Dan Tao: C'est vrai. Je n'essaie pas de le forcer sur lui. Si c'est ainsi que cela se passe, je m'excuse. Essayer simplement de suggérer ce que l'opinion (et plus de personnes) est la meilleure pratique. Mais tant que cela fonctionne pour eux et cela fait son travail; À savoir distinguer le privé des membres du public, continuez à basculer sur ce "m_".


8 Réponses :


6
votes

Non, non, il n'y a pas moyen de le faire, autrement que de simplement suivre votre propre convention et faire cela.Hello si vous avez vraiment besoin de passer par votre propriété publique.

Je ne vois pas pourquoi vous auriez besoin / que vous auriez besoin de le faire soit, comme possible votre classe interne, vous êtes celui qui contrôle le code et vous pouvez définir quoi / comment il est utilisé, donc il ne devrait donc pas 't être un problème.


2 commentaires

Woah! Désolé @Mitchel - j'ai accidentellement édité le mauvais message. Désolé pour ça.


@MARC - Avez-vous eu un peu de la charmant fonctionnalité de commande aléatoire? Cela a eu lieu plus d'une fois où je suppose automatiquement que ma question était dans la même position après une modification (ou une soumission) et a cliqué avec aveuglément le bouton d'édition. Ne vous aide pas lorsque la réponse dans cette position commence avec pratiquement le même texte.



1
votes

Non, fondamentalement. Eh bien, vous pourrait faire quelque chose avec les avertissements du compilateur via [obsolète] et #pragma , mais ce serait excessif.

vous pourriez < em> probablement le faire avec l'outillage, mais finalement vous devez faire confiance aux personnes de ne pas faire des choses stupides. Après tout, avez-vous des règles spéciales à propos de: xxx

ou faites-vous juste que "ne sois pas stupide"? ; p


3 commentaires

tandis que (true) plus pause à l'intérieur du corps de la boucle est une construction de programmation parfaitement valide. Il y a beaucoup de choses pires que ça.


@ToxicacAnger - mais sans le casse ?


Tout pourrait être justifié par cette ligne de raisonnement.



4
votes

non. Toute méthode à l'intérieur de la classe aura accès aux deux.

Votre équipe doit normaliser sur lequel utiliser (une variable de propriété ou privée).

Une fois que vous avez décidé à utiliser, vous pouvez essayer d'utiliser une règle personnalisée FXCOP pour appliquer la norme.


0 commentaires

1
votes

Vous ne devez accéder à la propriété que via la propriété publique Hello. C'est la raison de ce modèle. Si vous ajoutez une fonctionnalité à l'obtention ou à l'ensemble, si vous accédez à l'instance privée, vous introduirez des bugs dans votre code. Mais l'anwer est non, vous ne pouvez pas empêcher que quelqu'un d'appeler le privé lorsqu'il est à l'intérieur de votre classe qui change votre code.


2 commentaires

Sans doute, cela peut aller à la fois: vous voudrez peut-être référencer directement le champ de support afin que vous n'ayez pas affecté par aucun ajout à la propriété publique. Ce serait une bonne idée d'être cohérent à ce sujet, cependant, et éventuellement une bonne idée d'identifier clairement les variables de soutien qu'il est clair qu'une propriété est contournée. Par exemple, vous pouvez les suffixer avec _prop ou quelque chose comme ça.


Je préfère la consistance et je voulais juste signaler la raison du motif. Il y a toujours une raison pour chaque solution hors tension, ne se pratique pas de la meilleure pratique.



1
votes

Personnellement, je ne vois rien de mal à accéder au membre privé au sein de la classe. En fait, c'est ce que je fais généralement (sauf s'il y a une logique dans la propriété Getter / Setter que je souhaite toujours tirer parti de).

Cela a un sens pour moi: le code de la classe constitue la mise en oeuvre; Pourquoi cacher une implémentation de lui-même?

Voici un exemple de ce que je veux dire. Supposons que j'ai un membre, m_denominator , et je veux que ce ne soit jamais zéro: xxx

Je pourrais me dire à moi-même: "OK, partout je Définissez cette valeur dans cette classe, je devrais utiliser dénominateur pour vous assurer que je ne le réglais pas à zéro. " mais je suis tout à fait en contrôle de ce que je règle dénominateur à - je suis à l'intérieur de la classe! dans ce scénario Point de la logique dans la propriété Denominator est pour protéger la classe des valeurs non valides définies par code client. Il n'y a aucune excuse pour définir votre état interne à une valeur non valide dans la mise en œuvre d'une classe elle-même.

Bien sûr que ce n'est pas une règle absolue. Il existe sûrement des moments où l'utilisation de la propriété pour sa logique dans une classe peut être un choix sensible comme mesure de protection; Vraiment, je ne fais que discuter que c'est pas mal d'accéder aux membres privés d'une classe.


5 commentaires

Alors, que se passe-t-il lorsque vous revenez au code dans 6 mois pour ajouter une logique importante à la propriété Setter? Tout le code interne de votre classe sera désormais contourner les nouvelles implémentations.


Je préfère faire défaut l'utilisation de la propriété précisément parce que je ne veux pas garder une trace des endroits où la propriété fait quelque chose de spécial. L'optimiseur veillera généralement à optimiser l'appel de la méthode de toute façon, au moins pour un accesseur simple. Je n'utiliserai que la propriété quand je sais que la propriété fait quelque chose de "spécial" et je veux éviter cela à un but particulier.


@RR Herbie: Mais dans mon expérience, il est tout aussi probable que vous ajoutez une logique à la propriété, mais ne veut pas vouloir que la logique soit exécutée sur chaque accès se produisant dans la classe - uniquement sur les accès des accès du code externe. J'ai définitivement travaillé avec des développeurs qui ont ajouté la logique à leurs propriétés et qui ont tout d'un coup trouvé une partie de leur code se faisait être exécutée plus souvent que prévu. C'est un appel de jugement, évidemment; Je souligne simplement qu'il y a une différence entre cacher votre mise en œuvre du monde extérieur et la cacher de ... elle-même.


Je trouve ce raisonnement très suspect. En règle générale, vous mettez un code supplémentaire dans le constructeur de propriétés pour appliquer une certaine dépendance ou une règle d'entreprise. Mon expérience est que vous êtes généralement Ne voulez pas Voulez-vous éviter cela, même dans la classe. Il y a certainement des exceptions - et je voudrais faire référence à la propriété de soutien dans ces cas - mais parce qu'ils sont exceptionnels, j'utilise la propriété dans l'affaire par défaut plutôt que dans l'inverse. Référencer votre exemple, je dirais que dans l'initialisateur à l'aide du champ directement, c'est bien, mais n'importe où ailleurs dans votre classe, vous voulez vraiment utiliser la propriété.


@tvanfosson: Hé, je ne dis pas que tu as tort. Mon point de vue est fondamentalement: l'OP semble rechercher un moyen d'interdire l'accès à un membre privé de la mise en œuvre. Je dis: Ce n'est pas un nécessairement quelque chose que vous devez faire. En ce qui concerne quel type de logique devrait ou ne doit pas entrer dans une propriété Getter / Setter, c'est un argument différent. En tout cas, nous semblons tous deux disposés à concéder que parfois une approche est raisonnable et parfois l'autre approche a plus de sens; C'est tout ce que j'essaie vraiment de discuter - pas lequel est l'exception et qui est la règle.



8
votes

Vous pouvez accomplir cela via héritage:

abstract class A // A is not instantiatable due to being abstract
{
    private string m_hello = null;

    public string Hello
    {
         get{return m_hello;}
         set{m_hello = value;}
    }
}

class B : A
{
    // B now cannot access the private variable, use B in your code instead of A
}


0 commentaires

0
votes

Si vous vous trouvez vouloir masquer les détails de vous-même, cela peut être une odeur de code que votre classe a trop de responsabilités. Envisagez d'extraire l'une des responsabilités en une nouvelle classe.


2 commentaires

Parfois, ce n'est pas "toi-même" mais il y a d'autres membres de votre équipe qui ne pouvaient pas suivre les règles. Je sais, en théorie, tout a une solution simple, mais la vie est dure ...


@JOEWHITE: C'est un point de vue intéressant. Cependant, fragmentation de classes jusqu'à un niveau où chacun a une responsabilité presque triviale sonne bien en théorie, mais dans la pratique peut être un cauchemar à comprendre en sa propre raison.



12
votes

Comme d'autres ont suggéré que cela devrait être une réponse ...

Vous pouvez toujours utiliser des propriétés automatiques en C # 3 lors de la ciblage .NET 2.0, ainsi que Pas d'autres caractéristiques C # 3 . Contrairement à des arbres d'expression, les propriétés automatiques n'ont besoin de rien de spécial du CLR ou du cadre, au-delà du [compilergénerated] attribut (qui a été introduit dans .NET 2.0). < P> Donc, si vous utilisez VS2008 ou VS2010, il serait alors utile d'utiliser une propriété automatique.

Pour ce que ça vaut vraiment, je voudrais aussi cette capacité. J'aimerais pouvoir être capable de compromettre des variables dans une propriété: xxx

Je le considère comme un peu comme faire une variable privée en lecture seule - cela ne fait aucune différence pour les clients, mais aide à appliquer l'exactitude dans le code de classe lui-même.


2 commentaires

+1 - Je suis tout à fait d'accord avec la variable de propriété privée. J'aimerais vraiment que la capacité de Code arbitraire dans les méthodes de propriété et limite le champ de support à l'établissement uniquement pour que je n'évite pas accidentellement les "règles" dans le getter / code de réglage.


Tangentièrement liés, j'aimerais également les propriétés automatiques immuables (réglable via le constructeur ou la syntaxe d'initialisateur), puis seulement getable à partir de là-bas dans. Sontéré par un champ lisonly généré par le compilateur.