web-dev-qa-db-fra.com

Existe-t-il une meilleure façon d'utiliser les getters et setters sur les membres privés d'une classe?

J'ai cet exemple de classe:

public class Carrots
{
    private string name;

    public void SetName(string pName)
    {
        name = pName;
    }

    public string GetName()
    {
        return name;
    }
}

J'ai le membre de la classe défini comme privé et pour définir et obtenir ce membre, j'ai créé des méthodes get et set. Existe-t-il un moyen de rendre ce code plus court et plus facile à lire en un coup d'œil?

7
Gigabit

Utilisation des propriétés

Un getter et un setter appropriés ressembleraient à ceci:

public class Carrots
{
    private string name;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

( Cliquez ici si vous ne comprenez pas le rôle du mot-clé value dans cet exemple).

Utilisation des propriétés automatiques

Dans c # 3.0 et versions ultérieures, vous pouvez également utiliser auto-propriétés , ce qui le rend encore plus facile.

public class Carrots
{
    public string Name { get; set; }
}

Si vous souhaitez que la propriété publique soit en lecture seule (mais souhaitez toujours un setter privé), vous pouvez utiliser:

public class Carrots
{
    public string Name { get; private set; }
}

Comment l'appeler

Dans les deux cas, vous l'appeleriez ainsi:

var c = new Carrots();
c.Name = "This is a test!";
Console.WriteLine(c.Name); //outputs "This is a test!"
10
John Wu

Plus court et plus facile à lire serait quelque chose de similaire à:

public class Carrots
{
    public string Name { get; set; }
}

Cela utilise une variable privée interne qui est utilisée lors de l'accès à la propriété. Équivalent à:

public class Carrots
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

(Comme @John Wu l'a démontré.)

Cependant, cela dépendra de ce que vous voulez que le code externe puisse accéder.

Si vous voulez juste qu'un "Nom" soit instantanément modifiable et qu'il n'ait aucune incidence sur l'application lorsqu'elle l'est, la chaîne publique ci-dessus Nom {get; ensemble; } est tout ce dont vous aurez besoin.

Mais si vous suivez/utilisez/contrôlez la valeur d'une propriété dans votre classe et que vous ne voulez pas que le code externe la modifie, alors le deuxième exemple est celui qui vous convient.

Par exemple:

Vous avez une classe qui est créée avec une valeur connue. Vous voulez que cette valeur soit modifiée - mais sous votre contrôle.

Un solde bancaire peut-être? Ou la vitesse d'une voiture?

Allons avec la vitesse d'une voiture:

public class Car
{
    private string _speed;

    public string Speed
    {
        get { return _speed; }
    // Notice no setter in this case.
    }

    public void IncreaseSpeed()
    {
        if(_speed + 1 <= 100)
        {
            _speed++;
        }
    }

    public void Brake()
    {
        if(_speed-- >= 0)
        {
            _speed--;
        }
    }
}

Cela permet au code appelant d'augmenter la vitesse ou de ralentir en maintenant le frein autant de fois qu'il le souhaite. Mais vous pouvez maintenant mettre une limite réaliste à cette vitesse - l'utilisateur ne peut pas enfreindre les règles que vous avez dans le "monde" de votre application.

Voici un autre exemple, mais le code externe peut définir la valeur immédiatement:

public class Car
{
    private string _speed;

    public string Speed
    {
        get { return _speed; }
        set {
                if (value >= 0 && value <= 100)
                {
                    _speed = value;
                }
            }
    }
}

Cela permet désormais au code appelant de gérer l'accélération et le freinage, mettant à jour l'objet Car quand il le souhaite. Mais vous avez toujours le contrôle global de ce que cette valeur peut être, plutôt que de contrôler comment elle est modifiée.

En utilisant:

public class Carrots
{
    public string name;
}

comme l'a démontré @Charles Merriam, tout va bien si vous ne vous souciez pas quand et à quelle valeur, le code externe définira cette propriété. Il est toujours public et n'est jamais vérifié lorsqu'il est modifié.

Il ne devrait jamais être accédé par les méthodes internes de votre classe si elle nécessite des limites quant à l'état dans lequel elle doit se trouver ou requiert une plage particulière. Vous devez utiliser la logique de vérification des limites partout où vous y accédez (puis gérer les erreurs si les vérifications échouent), plutôt que d'empêcher complètement la saisie de données non valides.

1
Steve Padmore