8
votes

Y a-t-il une excuse pour avoir jeté une exception d'une conversion implicite?

de MSDN :

En éliminant les fonts inutiles, les conversions implicites peuvent améliorer la lisibilité du code source. Cependant, étant donné que des conversions implicites peuvent se produire sans les spécifier du programmeur, il faut prendre soin de prévenir des surprises désagréables. En général, les opérateurs de conversion implicites ne doivent jamais lancer d'exceptions et ne jamais perdre d'informations afin de pouvoir être utilisées en toute sécurité sans la conscience du programmeur. Si un opérateur de conversion ne peut pas répondre à ces critères, il devrait être marqué explicite.

Pendant que je ne suis pas en désaccord avec un point particulier, et je conviens que tout est très bon, y a-t-il déjà une raison suffisante pour justifier de casser la partie des conversions implicites qui ne lance pas d'exceptions?

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

  1. J'ai une fonction, qui renvoie un objet de collecte personnalisé (nous l'appellerons foocollection ).
  2. Cette fonction peut renvoyer des collections avec un seul élément et Il peut être déterminé à partir du code source si cela se produira ou non . (Par ceci, je veux dire juste l'appel de la fonction, pas la fonction elle-même)
  3. Si cela se produit, il est probable que l'utilisateur souhaite ce seul élément, plutôt qu'une collection avec un seul élément.

    Maintenant, je jette s'il faut inclure une conversion implicite de foocollection => foo pour masquer ce petit détail de mise en œuvre, mais cette conversion ne fonctionnera que s'il ya est un seul élément de la collection.

    est-il correct de lancer une exception dans ce cas? Ou devrais-je utiliser une fonte explicite à la place? Toute autre idée sur la manière dont je pouvais traiter cela (non, en raison des détails de la mise en œuvre, je ne peux pas simplement utiliser deux fonctions)?

    edit: Je pense que cela mérite de noter que foocollection ne met pas en œuvre aucune interface ou étendre réellement collection comme nom de nom pourrait impliquer, D'où les réponses à base de Linq sont inutiles. De plus, alors que la collection met en œuvre un indice numérique, il n'est pas le moyen le plus intuitif de traiter la collection car elle s'appuie principalement sur l'indice nommé.


0 commentaires

4 Réponses :


0
votes

La distribution doit être explicite. Il sera très étrange de pouvoir attribuer un foocollection à un FOO sans au moins une coulée.

Cela étant dit, les lancers IMHO ne sont pas un bon moyen de le faire. Même si vous le disez non, je vais utiliser une fonction parce que même si vous n'avez pas de contrôle sur la mise en œuvre de ces classes, vous pouvez au moins ajouter des méthodes d'extension comme FOO Tofoo (cette collection FOOCOLLECTION) Pour faire le travail.


2 commentaires

Je suis sûr que 50% sûr que cela ne fonctionne pas non plus que cela se trouve dans le contexte des types C # 4.0 et dynamique


c'est à dire. Je ne sais pas si le routage dynamique prend en compte des méthodes d'extension ou non. Dang ça, maintenant j'ai autre chose que je veux essayer!



11
votes

Je suis avec les lignes directrices: vous ne devriez jamais jeter d'une conversion implicite.

Je ne fournirais certainement pas une conversion implicite dans ce cas. Même l'idée d'une fonte explicite me sens tort: ​​ foo x = (foo) foocollection ne semble pas juste raison.

Pourquoi ne laissez-vous pas simplement le code appelant Vous inquiétez de la conversion de foocollection à foo ? Le code serait beaucoup plus intuitif pour tout le monde: xxx


5 commentaires

foo x = (foo) foocollection ne serait pas "juste" non plus (bien que cela soit compilé). foo x = (foo) foocollection.x () serait la façon dont il serait utilisé.


x () étant une fonction qui renvoie un sous-ensemble de 1 article de Foocollection.


De toute façon, vous essayez toujours de jeter une certaine collection de foo à foo lui-même, qui se sent bizarre pour moi. Pourquoi ne pas simplement laisser le code d'appel de foo x = foocollection.x () [0] ou quelque chose de similaire?


Entre autres choses, il se sent désordonné. Mais jetant une exception d'une conversion implicite ne se sent pas non plus. Oh bien, je suppose que tellement a parlé de toute façon quand même :)


Je voudrais que le mot est légèrement différent: tout instance d'objet qui jette jamais lors de la conversion implicite doit être considéré comme cassé. Si par ex. Une instance d'objet non threadsafe devient corrompue à la suite d'actions simultanées par plusieurs threads, il peut être approprié pour cette instance de jeter une exception dans ce qui serait normalement un typast d'élargissement, mais seulement parce que l'instance est cassée .



0
votes

Une copnversion implicite qui ne fonctionne que s'il n'y a que 1 article dans la collection? Donc, en fait, cela ne fonctionne pas la plupart du temps?

Je ne ferais jamais cette conversion implicite. Coller avec explicite. Si le programmeur utilisant votre fonction souhaite avoir le seul élément, il devrait simplement dire à votre classe.


0 commentaires

1
votes

Ce n'est clairement pas correct. jamais Utilisez des exceptions pour mettre en œuvre la logique!

Vous pouvez utiliser le linq-instruction foocollection.firstordfault () , qui donnera null ou le premier élément.


0 commentaires