56 votes

Quelle exception lancer à partir d'un setter de propriété ?

J'ai une propriété de type chaîne de caractères qui doit avoir une longueur maximale parce que les données sont liées à une base de données. Quelle exception dois-je lever si l'appelant tente de définir une chaîne dépassant cette longueur ?

Par exemple, ce code C# :

public string MyProperty
{
    get
    {
        return _MyBackingField;
    }
    set
    {
        if (value.Length > 100)
            throw new FooException("MyProperty has a maximum length of 100.");

        _MyBackingField = value;
    }
}

J'ai considéré ArgumentException mais ça ne semble pas juste. Techniquement c'est une fonction - MyProperty_set(string value) - donc un cas pour ArgumentException peut être faite, mais elle n'est pas appelée comme une fonction aux yeux du consommateur - elle se trouve à droite d'un opérateur d'affectation.

Cette question pourrait probablement être étendue à toutes sortes de validations de données effectuées dans les paramètres de propriétés, mais je suis particulièrement intéressé par le cas ci-dessus.

51voto

Richard Slater Points 2054

Jetez un coup d'œil dans mscorlib.dll avec Reflector, dans une situation similaire comme System.String.StringBuilder.Capacity Microsoft utilise ArgumentOutOfRangeException() similaire à :

public int PropertyA
{
    get
    {
        return //etc...
    }
    set
    {
        if (condition == true)
        {
            throw new ArgumentOutOfRangeException("value", "/* etc... */");
        }
        // ... etc
    }
}

19voto

Davide Vosti Points 1903

Pour moi, ArgumentException (ou un enfant) est plus logique, car l'argument (la valeur) que vous avez fourni n'est pas valide, et c'est pour cela que ArgumentException a été créé.

8voto

Martin Brown Points 8593

Je ne lèverais pas d'exception du tout. J'autoriserais plutôt une chaîne de caractères de n'importe quelle longueur et j'aurais une méthode "Validate" distincte sur la classe qui serait appelée avant l'enregistrement. Il existe un certain nombre de scénarios, en particulier si vous utilisez des liaisons de données, dans lesquels le fait de lancer des exceptions à partir des paramètres de propriété peut vous mettre dans le pétrin.

L'ennui, c'est que les programmeurs oublient d'attraper les exceptions provenant des paramètres de propriété. Cela dépend en quelque sorte du degré de propreté des données que vous souhaitez obtenir. Dans ce cas, je m'attendrais à ce que les longues chaînes de caractères soient courantes et non exceptionnelles et, en tant que tel, l'utilisation d'une exception serait un "contrôle de flux avec des exceptions".

Pour citer le site de Microsoft Directives de conception pour le développement de bibliothèques de classe :

N'utilisez pas d'exceptions pour le flux normal de contrôle, si possible. Sauf pour défaillances du système et les opérations avec conditions de course potentielles, le cadre les concepteurs de frameworks doivent concevoir les API de manière à ce que utilisateurs puissent écrire du code qui ne pas d'exceptions. Par exemple, vous pouvez fournir un moyen de vérifier les conditions préalables avant d'appeler un membre afin que les utilisateurs puissent écrire du code qui ne lève pas exceptions.

6voto

philsquared Points 13547

Vous vous souvenez que de nombreux problèmes en informatique sont résolus en ajoutant un niveau supplémentaire d'indirection ?

Une approche consisterait à créer un nouveau type, FixedLengthString, par exemple. Il s'agirait d'instances de que qui valident les longueurs des chaînes de caractères avec lesquelles ils sont initialisés - avec un opérateur de conversion pour effectuer la conversion de type à partir d'une simple chaîne de caractères. Si votre définisseur de propriété prend un tel type comme argument, toute violation deviendra une exception de conversion de type au lieu d'une exception d'argument/de propriété.

En pratique, je le fais rarement. C'est un peu pousser l'OO trop loin - mais dans certains cas, cela peut être une technique utile, donc je la mentionne ici pour être complet.

5voto

Evgeniy Krechun Points 542
public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}

via MSDN

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X