1
votes

Dois-je lever une exception ou retourner false?

Je développe un localisateur de service simple en C # en utilisant TDD.

Pour le moment, j'ai créé une méthode TryAddService qui ressemble à ceci:

    public bool TryAddService(Type type, object service)
    {
        if (service == null)
        {
            return false;
        }

        if (this.services.ContainsKey(type))
        {
            return false;
        }

        if (!type.IsAssignableFrom(service.GetType()))
        {
            return false;
        }

        this.services.Add(type, service);

        return true;
    }

Ma question est la suivante: devrais-je renvoyer false dans tous ces cas? Ou devrais-je lever une exception?

Mes clients dans ce scénario seraient d'autres développeurs.


1 commentaires

Puisqu'il retourne une valeur booléenne, il n'y aurait pas besoin de lever une exception, renvoyez simplement false.


3 Réponses :


0
votes

J'utilise ce scénario: J'ai une classe que tous les services renvoient cette classe nommée (MyReturn par exemple)

public MyReturn <bool> TryAddService(Type type, object service)
{
    if (service == null)
        return new MyReturn <bool> {Message = "Your messgage"};
    //and etc...
    return new MyReturn <bool>();
}

Maintenant votre service:

public sealed class MyReturn<TEntity> : IDisposable
{
    public string Message { get; set; }
    public TEntity Entity { get; set; }
    public string SysException { get; set; }
    // and etc...
    public void Dispose() {}
}

Dans votre formulaire u check Message, s'il est nul ou vide, vous n'avez aucune erreur .... Vous pouvez le personnaliser ...


0 commentaires

1
votes

Comme convenu officieusement, chaque fois que vous utilisez le modèle TryXXXX, votre méthode doit toujours réussir, mais renvoie le résultat de réussite réel sous forme de booléen. Si vous souhaitez lancer et Exception, supprimez simplement le mot "try" du nom de votre méthode.

En haut, si vous suivez le modèle TryXXXX, je vous recommande d'ajouter un bloc try-catch, pour vous assurer votre méthode réussit vraiment toujours:

public bool TryAddService(Type type, object service)
{
  if (service == null)
  {
    return false;
  }

  if (this.services.ContainsKey(type))
  {
    return false;
  }

  if (!type.IsAssignableFrom(service.GetType()))
  {
    return false;
  }

  try
  {
    this.services.Add(type, service);
  }
  catch
  {
    return false;
  }

  return true;
}


2 commentaires

Je ne suggérerais pas d'envelopper toute la fonction dans un try .. catch . Parce que si la ligne this.service.Add lèvera une exception pour une autre raison alors attendue, alors cette exception sera avalée.


@Fabio, c'est tout l'intérêt du modèle TryXXXX - NE JAMAIS lancer d'exception, quels que soient les problèmes, même si tout le système tombait en panne! Et l'exception potentielle n'est pas masquée - la fonction renvoie false dans le cas d'une exception pendant la méthode Add.



0
votes

Mes clients dans ce scénario seraient d'autres développeurs.

Pensez-vous que les consommateurs de votre classe enregistreront les types de manière conditionnelle?

public void TryAddService(Type type, object service)
{
    if (service == null)
    {
        throw new RegisterServiceException($"Can not register null for type '{type.FullName}'");
    }

    if (this.services.ContainsKey(type))
    {
        throw new RegisterServiceException($"Service for type '{type.FullName}' already registerd.");
    }

    if (!type.IsAssignableFrom(service.GetType()))
    {
        throw new RegisterServiceException($"Type '{type.FullName}' should be assignable from service of type '{service.GetType().FullName}'");
    }

    this.services.Add(type, service);
}

Ou les développeurs enregistreront simplement l'implémentation dont ils ont besoin et compteront sur le fait que TryAddService code> lèvera une exception lors du démarrage de l'application.

TryAddService(typeof(IService), new Service1());

En tant que développeur, je souhaite recevoir les commentaires les plus rapides possible si j'ai fait quelque chose de mal. Lancer une exception lors du démarrage de l'application (où généralement l'enregistrement du service est effectué) sera le retour le plus rapide possible. À moins que vous n'utilisiez des génériques avec des contraintes, qui fourniront des commentaires au début de la compilation.

Si les développeurs n'ont pas de logique pour l'échec de l'enregistrement, ne renvoyez rien, mais lancez une exception personnalisée avec un message descriptif

if (TryAddService(typeof(IService), new Service1()))
{
    // Added successfully - what to do next
}
else
{
    // What here? Try another service?
}

0 commentaires