Refactoring Des Clauses De Garde

Quelles approches les gens prennent-ils (le cas échéant) dans la gestion de l'explosion de la clause guard dans vos classes? Par exemple:

public void SomeMethod<T>(string var1, IEnumerable<T> items, int count)
{
    if (string.IsNullOrEmpty(var1))
    {
        throw new ArgumentNullException("var1");
    }

    if (items == null)
    {
        throw new ArgumentNullException("items");
    }

    if (count < 1)
    {
        throw new ArgumentOutOfRangeException("count");
    }

    ... etc ....
}

Dans le projet sur lequel je travaille actuellement, il existe de nombreuses classes qui ont un ensemble similaire de clauses de garde sur les méthodes publiques.

Je suis au courant des contrats de Code.net 4.0, mais ce n'est pas une option pour notre équipe pour le moment.

23
demandé sur Community 2009-10-21 03:27:40

5 réponses

Beaucoup de projets que j'ai vus utilisent une classe statique Guard.

public static class Guard {
    public static void ArgumentIsNotNull(object value, string argument) {
        if (value == null)
            throw new ArgumentNullException(argument);
    }
}

Cela rend le code beaucoup plus propre, à mon avis.

Guard.ArgumentIsNotNull(arg1, "arg1");
41
répondu David Brown 2011-11-25 12:49:07

Si vous ne voulez pas descendre la route des contrats de Code, une façon de la simplifier est de supprimer les accolades:

public void SomeMethod<T>(string var1, IEnumerable<T> items, int count)
{
    if (string.IsNullOrEmpty(var1))
        throw new ArgumentNullException("var1");

    if (items == null)
        throw new ArgumentNullException("items");

    if (count < 1)
        throw new ArgumentOutOfRangeException("count");

    ... etc ....
}

Autre que cela, il y a quelques façons que vous pouvez simuler des contrats de Code, si votre objection est que. NET 4.0 n'est pas encore prime time:

Http://geekswithblogs.net/Podwysocki/archive/2008/01/22/118770.aspx

4
répondu Robert Harvey 2009-10-20 23:35:49

Vous pouvez envisager de refactorer pourintroduire un objet nul .

4
répondu Todd Stout 2009-10-21 00:03:50

En attendant, il y a un excellent article à ce sujet ici: http://haacked.com/archive/2013/01/05/mitigate-the-billion-dollar-mistake-with-aspects.aspx/

Je considérerais utiliser NullGuard.Fody comme je suis excité par les capacités de Fodys à réduire le code standard

3
répondu mamuesstack 2015-02-07 08:06:08

Une approche pour réduire (pas supprimer complètement) le nombre de clauses de garde est de comprendre la cause de leur existence. Assez souvent, il s'avère que nous nous gardons des valeurs qui sont valides pour le type de l'argument, mais pas pour la méthode qui les accepte. En d'autres termes, la méthode est définie sur un sous-ensemble du domaine défini par le type d'argument.

La Solution à cette catégorie de cas est d'essayer de définir un sous-type (par exemple une interface plus restrictive) et d'accepter ce type comme argument. Vous pouvez trouver un exemple illustratif dans cet article: Pourquoi avons-nous besoin de clauses de garde?

Bien sûr, cette technique ne s'applique pas à tous les cas. Tous les types de référence autorisent au moins les références nulles. Par conséquent, la plupart de nos méthodes seront définies sur une partie du domaine, ce qui nécessite une clause de garde contre null.

Mais du côté positif, cette technique aide à faire prendre conscience des méthodes qui reçoivent des arguments plus généraux que souhaités. Plomberie ce trou contribue à améliorer la conception en général.

3
répondu Zoran Horvat 2015-08-19 20:16:49