8 votes

Y a-t-il jamais une excuse pour lancer une exception à partir d'une conversion implicite ?

De MSDN :

En éliminant les casts inutiles, les conversions implicites peuvent améliorer la lisibilité du code source. Cependant, comme les conversions implicites peuvent se produire sans que le programmeur ne les spécifie, il faut veiller à éviter les mauvaises surprises. En général, les opérateurs de conversion implicites ne doivent jamais lever d'exceptions et ne doivent jamais perdre d'informations, de sorte qu'ils puissent être utilisés en toute sécurité sans que le programmeur en ait conscience. Si un opérateur de conversion ne peut pas répondre à ces critères, il doit être marqué explicite.

Bien que je ne sois pas en désaccord avec un point particulier, et que je sois d'accord pour dire que tout cela est très bien, y a-t-il jamais une raison suffisamment importante pour justifier la rupture de la partie concernant les conversions implicites qui ne lèvent pas d'exceptions ?

Le cas particulier que j'ai devant moi est un cas où :

  1. J'ai une fonction, qui renvoie un objet de collection personnalisé (nous l'appellerons FooCollection ).
  2. Cette fonction peut retourner des collections avec un seul élément, et on peut déterminer à partir du code source si cela se produira ou non . (j'entends par là l'appel de la fonction, pas la fonction elle-même).
  3. Si cela se produit, il y a 99,9 % de chances que l'utilisateur veuille cet élément unique, plutôt qu'une collection contenant un seul élément.

Maintenant, je me demande s'il faut inclure une conversion implicite de l'anglais au français. FooCollection => Foo pour masquer ce petit détail d'implémentation, mais cette conversion ne fonctionnera que s'il n'y a qu'un seul élément dans la collection.

Est-il possible de lancer un Exception dans ce cas ? Ou devrais-je plutôt utiliser un cast explicite ? Avez-vous d'autres idées sur la façon dont je pourrais traiter ce problème (non, en raison de détails de mise en œuvre, je ne peux pas simplement utiliser deux fonctions) ?

EDITAR: Je pense qu'il convient de noter que FooCollection n'implémente aucune interface ou n'étend pas réellement Collection comme son nom l'indique, les réponses basées sur LINQ sont donc inutiles. De plus, bien que la collection implémente un index numérique, ce n'est pas la manière la plus intuitive de traiter la collection car elle repose principalement sur l'index nommé.

11voto

LukeH Points 110965

Je suis d'accord avec les directives : Vous ne devriez jamais lancer une conversion implicite.

Je ne proposerais certainement pas une conversion implicite dans ce cas. Même l'idée d'une conversion explicite me semble fausse : Foo x = (Foo)fooCollection ça ne semble pas juste.

Pourquoi ne pas laisser le code d'appel se préoccuper de la conversion de FooCollection a Foo ? Le code serait beaucoup plus intuitif pour tout le monde :

Foo a = fooCollection[0];
Foo b = fooCollection.First();
Foo c = fooCollection.FirstOrDefault();
// etc

1voto

Thomas Weller Points 8428

Il est clair que ça ne va pas. Jamais. utiliser les exceptions pour mettre en œuvre la logique !

Vous pouvez utiliser le Linq-Statement FooCollection.FirstOrDefault() qui donnera null ou le premier élément.

0voto

Julien Lebosquain Points 20894

Le casting doit être explicite. Il sera très étrange de pouvoir assigner un FooCollection à un Foo sans au moins un plâtre.

Ceci étant dit, les moulages ne sont pas une bonne façon de faire. Même si vous dites non, j'utiliserai une fonction car même si vous n'avez pas le contrôle sur l'implémentation de ces classes, vous pouvez au moins ajouter des méthodes d'extension telles que Foo ToFoo(this FooCollection collection) pour faire le travail.

0voto

Maximilian Mayerl Points 6335

Une copnversion implicite qui ne fonctionne que s'il n'y a qu'un seul élément dans la collection ? Donc, en fait, cela ne fonctionne pas la plupart du temps ?

Je ne ferais jamais cette conversion implicite. Restez-en à l'explicite. Si le programmeur qui utilise votre fonction veut avoir l'élément unique, il doit simplement le dire à votre classe.

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