web-dev-qa-db-fra.com

Quand utiliser InvalidOperationException ou NotSupportedException?

J'implémente une implémentation de collection personnalisée qui peut être en lecture seule ou non en lecture seule; c'est-à-dire que toutes les méthodes qui modifient la collection appellent une fonction qui est l'équivalent moral de:

private void ThrowIfReadOnly() {
    if (this.isReadOnly)
       throw new SomeException("Cannot modify a readonly collection.");
}

Je ne sais pas lequel de NotSupportedException ou InvalidOperationException je devrais utiliser dans ce cas.

39
Jean Hominal

Le MSDN n'a qu'un seul guide sur ce sujet précis, sur NotSupportedException :

Pour les scénarios où il est parfois possible pour l'objet d'exécuter l'opération demandée et où l'état de l'objet détermine si l'opération peut être effectuée, voir InvalidOperationException .

Ce qui suit est purement ma propre interprétation de la règle:

  • Si l'état de l'objet peut changer de sorte que l'opération peut devenir invalide/valide pendant la durée de vie de l'objet, alors InvalidOperationException doit être utilisé.
  • Si l'opération est toujours invalide/valide pendant toute la durée de vie de l'objet, alors NotSupportedException doit être utilisé.
  • Dans ce cas, "durée de vie" signifie "tout le temps que n'importe qui peut obtenir une référence à l'objet" - c'est-à-dire, même après un appel à Dispose() qui rend souvent la plupart des autres méthodes d'instance inutilisables;
    • Comme l'a souligné Martin Liversage, dans le cas où un objet a été éliminé, le type ObjectDisposedException plus spécifique doit être utilisé. (C'est toujours un sous-type de InvalidOperationException).

L'application pratique de ces règles dans ce cas serait la suivante:

  • Si isReadOnly ne peut être défini qu'au moment de la création de l'objet (par exemple un argument constructeur), et jamais à aucun autre moment, alors NotSupportedException doit être utilisé.
  • Si isReadOnly peut changer pendant la durée de vie de l'objet, alors InvalidOperationException doit être utilisé.
    • Cependant, le point de InvalidOperationException vs NotSupportedException est en fait théorique dans le cas de l'implémentation d'une collection - étant donné la description de IsReadOnly sur MSDN, le seul le comportement autorisé pour IsReadOnly est que sa valeur ne change jamais après l'initialisation de la collection. Cela signifie qu'une instance de collection peut être modifiable ou en lecture seule - mais elle doit en choisir une à l'initialisation et la conserver pour le reste de sa durée de vie.
55
Jean Hominal