2
votes

Getters et Setters versus méthode de classe

Je demande une recommandation d'utilisation des getters et des setters. J'ai écrit le même code en deux versions: en utilisant des getters et des setters et en utilisant uniquement la méthode de classe. Et je ne vois pas clairement la différence entre eux.

J'ai écrit le livre de classe avec l'évaluation du champ privé. Et le constructeur Book peut attribuer quelque chose à Book.rating par RatingSetter ou par RatingMethod. RatingMethod ne définit que les valeurs, mais je peux également créer une méthode uniquement pour obtenir des valeurs.

class Book
    {
        public string title;
        public string author;
        private string rating;

        public Book(string title, string author, string rating)
        {
            this.title = title;
            this.author = author;
            RatingSetter = rating;
            RatingMethod(rating);
        }

        public string RatingSetter
        {
            get { return this.rating; }
            set
            {
                if (value == "PG" || value == "PG-13" || value == "R")
                {
                    rating = value;
                }
                else
                {
                    rating = "NR";
                }
            }
        }

        public string RatingMethod(string rating)
        {
            if (rating == "PG" || rating == "PG-13" || rating == "R")
            {
                return this.rating = rating;
            }
            else
            {
                return this.rating = "NR";
            }
        }
    }

À mon avis, il n'y a aucune différence sur la sécurité, la validation ou quoi que ce soit. Quelqu'un pourrait-il me guider et m'aider à comprendre quelle est la différence et pourquoi est-il recommandé d'utiliser des getters et des setters.


5 commentaires

Ils font la même chose en interne. La différence réside dans la sémantique de la façon dont vous les utilisez.


Je ne suis pas d'accord avec le commentaire et la réponse. Pourquoi les propriétés sont importantes


@Crowcoder: L'une des premières phrases de l'article que vous liez déclare: "Il vaut la peine d'être clair que cet article ne traite pas de la question de savoir si quelque chose doit être une méthode ou une propriété." Ce qui est exactement ce qui est demandé dans la question ci-dessus. Donc, si l'article auquel vous faites référence ne répond pas explicitement à cette question, que suggérez-vous exactement?


@David ce n'est pas ainsi que j'ai interprété la question mais je comprends votre point de vue. Je l'ai pris de manière plus générale, pas tellement "est-ce que cette chose spécifique doit être une propriété ou doit-elle être une méthode?"


@David, il est intéressant de noter que cela a été marqué comme un doublon d'une question plus générale des meilleures pratiques à laquelle Jon Skeet a répondu. Votez-vous pour la réouverture?


3 Réponses :


0
votes

La fonctionnalité est la même. Mais cela rend le code plus lisible et compréhensible.

Dans votre exemple, vous validez rating en appelant RatingSetter ou RatingMethod . Considérez que vous travaillez en équipe et que votre collègue ne connaît pas les méthodes de validation et appelle simplement this.rating = someValue . Avec votre exemple, il n'y aurait aucune validation. Mon exemple de code (non testé) garantit que la validation est effectuée sur chaque attribution de valeur.

private string rating {
     get { return this.rating; }
        set
        {
            if (value == "PG" || value == "PG-13" || value == "R")
            {
                rating = value;
            }
            else
            {
                throw new UnknownRatingException();

            }
        }
}

public Book(string title, string author, string rating)
    {
        this.title = title;
        this.author = author;
        this.rating = rating //the set property is called
    }


5 commentaires

Pourquoi est-il plus lisible et compréhensible? Pouvez-vous montrer les deux façons d'expliquer?


J'utiliserais throw new UnknownRatingException () dans la clause else à la place pour montrer un cas d'utilisation particulier


Votre réponse empire. Votre dernier paragraphe ne répond pas à la question et ne fait que confondre le sujet. La question est de savoir pourquoi un moyen est préférable à l'autre. Il ne s'agit pas de la nécessité des méthodes. Ce n'est pas non plus une question de sécurité.


Mon exemple montre comment vous pouvez réduire votre code en utilisant des setters et des getters. Pour cette raison, vous pouvez vous débarrasser de certaines méthodes supplémentaires. Et je n'ai pas écrit que c'était absolument sûr, j'ai écrit que c'était plus sûr.


@AlinaJ - Non, ce n'est pas le cas. Vous devez montrer les deux manières d'écrire le code, puis discuter des différences. En outre, il n'y a aucun avantage de validation pour les propriétés par rapport aux méthodes.



5
votes

Les getters et setters ne sont que du sucre syntaxique. Le compilateur compilera vos getters et setters dans les méthodes getter et setter éventuellement. Donc, en écrivant vous-même les méthodes getter et setter, vous faites en quelque sorte le travail du compilateur.

Par conséquent, je vous recommande d'utiliser des getters et des setters, car l'un de leurs principaux objectifs est de remplacer les méthodes getter et setter. p>

Voici quelques autres avantages de l'utilisation des getters et des setters:

  • Les getters et les setters peuvent vous faire gagner beaucoup de temps si vous n'avez besoin que de getters et setters sans aucune logique:

    obj1.SetProperty(obj1.GetPropert() + obj2.GetProperty());
    
  • IMO, l'esthétique des getters et des setters est meilleure. Comparez:

    obj1.Property += obj2.Property;
    

    avec

    public int Property { get; set; }
    

    J'ai l'impression que ce dernier a juste trop de parenthèses ...

  • Gardez les setters et getters près de la déclaration de propriété. Si vous utilisez les méthodes getter et setter, vous pourriez accidentellement écrire d'autres méthodes entre la déclaration de propriété et les méthodes getter / setter, provoquant une lente «dérive» des méthodes getter / setter de la déclaration de propriété. La prochaine fois que vous voudrez le trouver, vous devrez faire défiler vers le haut et vers le bas. Avec les getters et les setters, ils seront toujours sous la déclaration de propriété.


3 commentaires

J'étais sur le point de comprendre, mais je commence à relire votre message plusieurs fois et maintenant je suis totalement perdu. Je sais que ces propriétés ne sont que du sucre syntaxique, mais je ne vois pas pourquoi. - Si je n'ai besoin que de propriété sans aucune logique. Comparez: public int Property {get; ensemble; } et public int property; - Si j'ai besoin d'une logique comme une validation, j'ai écrit le code de comparaison dans le premier post.


@morhhn public int property; est un fichier, pas une propriété. Et les champs publics sont très déconseillés.


@morhhn Ceci et ceci < / a> pourrait aider.



1
votes

Depuis Microsoft a >,

Une propriété est un membre qui fournit un mécanisme flexible pour lire, écrire ou calculer la valeur d'un champ privé.

Ce qui est essentiellement leur façon de dire qu'une propriété est un membre spécialement conçu, qui existe uniquement pour envelopper et accéder aux membres privés, permettant aux "données d'être facilement accessibles tout en aidant à promouvoir la sécurité et la flexibilité de méthodes. "

Dans votre exemple, je renommerais RatingSetter simplement en Rating et le traiterais comme si vous le feriez comme un champ public normal. Cela favorise la facilité d'utilisation et réduit la confusion lorsque d'autres personnes utilisent votre code. Ce que vous faites et ce qui doit être fait est plus évident.

Il est également déconseillé d'avoir des champs publics, par exemple public string title; Au lieu de cela, il est généralement préférable d'opter pour l'utilisation d'une propriété pour envelopper ce champ et le rendre privé, par exemple.

private string title;
public string Title 
{
    get{ return title;}
    set
    {
        // Logging Code Here
        title = value;
    }
}

Vous pouvez ensuite utiliser la propriété publique en dehors de votre classe, mais vous avez maintenant plus de contrôle sur ce qui se passe quand quelqu'un accède ou définit la variable.

private string title;
public string Title {get; private set;}

Ce qui autorisera uniquement l'accès en lecture depuis l'extérieur de la classe.

La journalisation est désormais plus facile, puisque vous pouvez l'implémenter dans le setter:

private string title;
public string Title {get; set;}


10 commentaires

Pourquoi plus flexible? Pourquoi plus cohérent?


Plus flexible qu'un champ public standard car vous avez la possibilité d'ajouter plus de fonctionnalités dans le corps de la propriété. Plus cohérent car il émule plus évidemment les accès et l'écriture de la propriété.


@Enigmativity Parce que vous pouvez enregistrer les accès aux getters / setters. Vous pouvez transformer les valeurs avant de les obtenir / de les définir. Par exemple Minute {get} et Hour {get} et ne stockez qu'une seule valeur à partir de laquelle elle sera calculée. Vous pouvez donner accès aux propriétés d'un autre champ int ProductId => _product.Id . Vous pouvez autoriser uniquement la définition ou uniquement l'obtention de la propriété. Ou modificateur d'accès différent pour chacun. Avec Field, vous ne pouvez pas faire ces choses.


@ OndřejKubíček - La question ne concerne pas les champs.


@Enigmativity Et à propos de quoi?


@DanielMackenzie - La question ne concerne pas les champs. Et que signifie "émuler de manière plus évidente les accès et l'écriture à la propriété"?


@ OndřejKubíček - la différence entre les propriétés et les méthodes.


@Enigmativity Par exemple, vous ne pouvez pas écrire getter pour int, mais setter pour double avec le même nom. Les méthodes setter et getter peuvent être nommées de différentes manières et dérouter l'utilisateur. ( GetId () , getid () od Id () ) Et avec les propriétés, l'appel semble beaucoup mieux sans autant de parenthèses.


@Enigmativity Excuses, après avoir relu ce que j'ai écrit à la hâte, je voulais dire quelque chose de plus du genre "émuler le terrain". Par là, je veux dire que c'est le meilleur des deux mondes, un terrain d'entente entre une méthode et un terrain ordinaire. C'est concis et la fonctionnalité évidente, comme un champ. mais avec toute la puissance et la flexibilité d'une méthode de support.


@DanielMackenzie - Vous auriez dû avoir la déclaration "C'est concis et la fonctionnalité évidente, comme un champ, mais avec toute la puissance et la flexibilité d'une méthode" (légèrement modifiée) dans votre réponse.