Valider les données du constructeur

voix
3

Une classe d'exemple dans « classe C # Desing Manuel » (p 137) ne remet pas la méthode de validation des cours pour un domaine spécifique à l'intérieur des classes que constructeur. Donc, fondamentalement, la classe d'échantillon vous permet de créer un objet avec des données incorrectes et ne jette une erreur pour que les données lorsque vous appelez qui fait la validation sur elle alors la propriété du terrain. Donc, vous avez maintenant un mauvais objet et ne pas savoir qu'après le fait.

Je ne ai jamais compris pourquoi ils ne l'appellent pas seulement la propriété du constructeur jetant ainsi une erreur immédiatement si de mauvaises données se trouve lors de l'initialisation? Je les ai envoyé en vain ...

J'ai tendance à utiliser le format suivant en appelant mes propriétés de mes constructeurs - cette structure est appropriée pour valider les données d'initialisation? ty

class Foo
{
    private string _emailAddress;

    public Foo(string emailAddress)
    {
        EmailAddress = emailAddress;
    }

    public string EmailAddress
    {
        get { return _emailAddress; }
        set
        {
            if (!ValidEmail(value))
                throw new ArgumentException
                    (string.Format
                    (Email address {0} is in wrong format, 
                    value));

            _emailAddress = value;
        }
    }


    private static bool ValidEmail(string emailAddress)
    {
        return Regex.IsMatch
            (emailAddress, @\b[A-Z0-9._%+-]+ +
                           @@[A-Z0-9.-]+\.[A-Z]{2,4}\b,
                           RegexOptions.IgnoreCase);
    }
}
Créé 26/08/2009 à 23:59
source utilisateur
Dans d'autres langues...                            


5 réponses

voix
2

Il me fait aucun sens de ne pas valider les données dans le constructeur. Comme vous le soulignez, l'objet peut se retrouver dans un état non valide. Compte tenu de cette conception, vous ne seriez pas même se rendre compte que vous avez eu de mauvaises données lors de l'appel du getter.

Pour tout de complexité modérée ou plus, j'ai tendance à utiliser un Broken Rules approche plutôt que immédiatement lancer une exception. Dans cette approche, je définir un objet BrokenRules qui contient des informations sur la classe et la propriété qui est invalide, et la raison pour laquelle il est invalide. Puis, dans une classe de base commune, je définir une liste de tenir une liste sur l'objet de tout « mauvais ». Une propriété (encore une fois dans la classe de base) IsValid indique s'il existe actuellement des règles cassées.

L'avantage est qu'il pourrait potentiellement y avoir plusieurs choses de mal à l'état d'objet. Si un utilisateur est invité à corriger les problèmes (c.-à cet objet est défini à partir d'une interface utilisateur), fournissant une liste de tous les problèmes permet à l'utilisateur de les corriger en une seule fois, plutôt que de fixer une erreur juste pour être dit qu'il y en a un autre. Et un autre. Etc.

Créé 27/08/2009 à 00:07
source utilisateur

voix
2

Oui, si votre approche générale est:

Assurez -vous que vous ne pouvez obtenir une instance d'un validobjet

je l'aime.

Les constructeurs devraient être utilisés pour créer des objets qui sont immédiatement valides, ne pas créer juste un « contenant », des choses à mettre en.

Créé 27/08/2009 à 00:03
source utilisateur

voix
2

Eh bien, pour l'un, vous êtes susceptible d'obtenir la NullReferenceException redoutée, puisque vous n'êtes pas vérifier si emailAddress est nulle à tous les niveaux. Cette vérification particulière doit être fait dans le constructeur lui-même, et si emailAddress est nulle, jetez un ArgumentNullException. Pour le reste, je ne vois pas de problème particulier avec elle comme il est écrit dans votre échantillon. Cependant, il y a des problèmes qui peuvent survenir si vous faites la propriété virtuelle, et d'en tirer les enfants de cette classe. Exécution ordre d'initialisation du champ, base et consturctors de classe dérivée devient alors un problème, et vous devez être prudent.

Créé 27/08/2009 à 00:03
source utilisateur

voix
0

la validation se produit lorsque l'adresse e-mail est définie. C'est là que vous le voulez parce que l'adresse e-mail pourrait être réglé plus tard.

Si vous avez aussi appelé validation dans le constructeur, vous gagnerais un appel de validation supplémentaire, redondant (une fois quand construit, un autre lorsque l'adresse e-mail est définie dans le constructeur).

Créé 27/08/2009 à 00:04
source utilisateur

voix
0

Je ne vois rien de mal à cette approche. Vous pouvez appeler des méthodes sur ce dans le constructeur, et setters de propriété / getters sont le sucre syntaxique pour que les appels de méthode.

Créé 27/08/2009 à 00:03
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more