Question

Remarque: il ne s'agit pas de une copie de la question de Jeff .

Cette question a été posée "Est-ce un équivalent?" Je sais qu'il n'y en a pas et je veux savoir pourquoi!

La raison pour laquelle je pose cette question est que je viens juste de comprendre à quel point c'est important et que la conclusion me semble très étrange.

Le bloc Gestion des exceptions de la bibliothèque d'entreprise de Microsoft nous conseille d'utiliser ce modèle:

catch (Exception x)
{
    if (ExceptionPolicy.HandleException(x, ExceptionPolicies.MyPolicy))
        throw;

    // recover from x somehow
}

La stratégie étant définie dans un fichier XML, cela signifie que si un client a un problème, nous pouvons la modifier pour faciliter le traçage (ou éventuellement le masquage) du problème afin de lui donner une résolution rapide jusqu'à résolution du problème. avec elle correctement - ce qui peut impliquer de discuter avec des tierces parties, de la faute de qui tout est.

Il s'agit essentiellement d'une reconnaissance du simple fait que, dans les applications réelles, le nombre de types d'exception et leur "capacité de récupération" le statut est pratiquement impossible à gérer sans une telle installation.

Pendant ce temps, l’équipe CLR chez MS dit que ce n’est pas une option, et il s’avère que ces gars-là savent de quoi ils parlent! Le problème est que juste avant l’exécution du bloc catch , tous les blocs finally imbriqués dans le bloc try seront exécutés. Ainsi, ces blocs finally peuvent effectuer les opérations suivantes:

  • Modifiez sans problème l'état du programme (ouf, chanceux).
  • Détachez quelque chose d'important dans les données du client, car l'état du programme est mal connu.
  • Déguisez ou détruisez des éléments de preuve importants pour diagnostiquer un problème, surtout s'il s'agit d'appels en code natif.
  • Lancez une autre exception, ce qui ajoute à la confusion et à la misère.

Notez que l'instruction utilisant et les destructeurs C ++ / CLI sont construits sur try / finally , de sorte qu'ils sont également affectés.

Donc, clairement, le modèle catch / throw pour filtrer les exceptions n'est pas bon. Ce qui est réellement nécessaire, c’est un moyen de filtrer les exceptions, via une politique, sans les intercepter réellement et ainsi déclencher l’exécution de blocs finally , à moins que nous ne trouvions une politique qui indique que l’exception peut être récupérée en toute sécurité. .

L’équipe CLR a récemment publié un blog à ce sujet:

Le résultat est que nous devons écrire une fonction d'assistance dans VB.NET pour nous permettre d'accéder à cette capacité vitale à partir de C #. Le gros indice qu'il y a un problème est qu'il y a du code dans la BCL qui le fait. Beaucoup de gens ont écrit sur le blog pour le faire, mais ils mentionnent rarement, voire jamais, la chose à propos de essayer / enfin , qui est le tueur.

Ce que j'aimerais savoir, c'est:

  • Existe-t-il des déclarations publiques ou des courriels directs que l'équipe C # a envoyés à ce sujet?
  • Existe-t-il des suggestions Microsoft Connect existantes demandant cela? J'ai entendu des rumeurs à leur sujet, mais aucun des mots clés probables n'a abouti.

Mettre à jour : comme indiqué ci-dessus, j'ai déjà effectué une recherche sur Microsoft Connect sans rien trouver. J'ai aussi (sans surprise) googlé. Je n'ai trouvé que des personnes expliquant pourquoi elles ont besoin de cette fonctionnalité , ou les soulignant. les avantages dans VB.NET , ou en espérant que ce soit ajouté dans une future version de C # ou y remédier , et beaucoup de conseil trompeur . Mais aucune explication sur la raison de son omission de toutes les versions actuelles de C #. Et la raison pour laquelle je pose des questions sur les problèmes existants liés à Connect, c'est pour que (a) je ne crée pas de doublon inutile et (b) je puisse dire aux personnes intéressées si je dois en créer un.

Mise à jour 2: un ancien blog intéressant d'Eric Gunnerson , anciennement de l'équipe C #:

  

"Oui, pouvoir imposer une condition   une prise est un peu plus pratique   que d'avoir à écrire le test   vous-même, mais cela ne permet pas vraiment   que vous fassiez quelque chose de nouveau. "

C’était la même hypothèse que j’avais jusqu’à ce que cela m’ait été correctement expliqué!

Était-ce utile?

La solution

Quant aux bugs de connexion existants. Le problème suivant concerne les fliters d’exception. L'utilisateur n'a pas explicitement déclaré qu'il souhaitait qu'il soit un filtre réel au sens où il s'exécute, mais à mon humble avis, cela est sous-entendu par la logique.

https://connect.microsoft.com/VisualStudio/feedback /ViewFeedback.aspx?FeedbackID=401668

Hormis ce problème, il n’ya aucun problème que je puisse trouver ni savoir qui soit lié à ce que vous recherchez. Je pense qu'il serait bon d'avoir un problème séparé qui appelle explicitement le besoin de filtres d'exception de style VB.Net.

Je ne voudrais pas trop m'inquiéter d'introduire une question en double si vous avez fait un peu de diligence raisonnable pour en rechercher une existante. S'il y a une dupe, Mads la dupliquera en conséquence et vous liera à la requête principale.

En ce qui concerne l’obtention d’une réponse officielle de la part de l’équipe C #, vous obtiendrez probablement cela lorsque vous 1) créez un bogue de connexion ou 2) soyez dupé contre le bogue principal. Je doute vraiment qu'il y ait une raison / justification officielle en ce moment.

Voici mes spéculations sur le sujet: je suppose que cette fonctionnalité ne faisait tout simplement pas partie de l'ensemble de fonctionnalités C # 1.0 d'origine et que, depuis cette date, la demande n'a pas été suffisante pour en faire partie. la langue. Les équipes C # et VB passent beaucoup de temps à classer les fonctionnalités linguistiques au début de chaque cycle de navigation. Nous devons parfois faire des coupes très difficiles. Sans demande suffisante, il y a très peu de chance qu'une fonctionnalité apparaisse dans la langue.

Jusqu'à récemment, je parie que vous auriez du mal à trouver une personne sur 10 qui comprend la différence entre Try / When de VB.Net et qui utilise simplement une déclaration old old if dans un bloc C #. Cela semble un peu plus préoccuper les esprits ces derniers temps, alors peut-être que cela en fera une version future du langage.

Autres conseils

L'utilisation de Injection de filtre d'exception peut être plus simple que d'utiliser la solution de contournement du délégué.

Pour une vraie réponse à votre question, vous aurez besoin d’une réponse d’Anders Hejlsberg, ou de quelqu'un qui participait aux réunions de conception initiale. Vous pourriez essayer de voir si l'intervieweur de Channel 9 pourrait vous poser la question la prochaine fois. l'équipe de conception C # est interviewée .

Je suppose que lorsque la décision initiale a été prise, les filtres d’exception étaient considérés comme une complication inutile qui pourrait faire plus de mal que de bien. Vous pouvez certainement constater une volonté de garder le silence sur les caractéristiques non prouvées de cette interview concernant la décision de ne pas prendre en charge les exceptions vérifiées: Le problème des exceptions vérifiées .

Je pense que les scénarios de diagnostic postmoterm plaident fortement en faveur de l'accès aux filtres d'exception dans le langage. Cependant, ces scénarios n'ont peut-être pas été articulés à l'époque. De plus, ces scénarios nécessitent réellement une prise en charge appropriée de l’outillage, qui n’était certainement pas disponible dans la V1. Enfin, l’ajout de cette fonctionnalité que nous n’envisageons pas peut avoir de gros inconvénients.

S'il n'y a pas de bogue de connexion à ce sujet, vous devez en entrer un et encourager les autres à le voter. [Je recommanderais de demander l'accès à la fonctionnalité CLR plutôt que d'essayer de concevoir comment elle s'intègre dans la langue.]

Je ne crois pas non plus que Java dispose d'une option de filtrage. En supposant que si cela se produisait, nous en verrions aussi un en C #. VB.net en a probablement un par hasard étant donné que l’équipe de VB a commencé avec une table rase.

Une chose qui pourrait jouer en votre faveur pour obtenir cette option dans une future version de C # est l’objectif déclaré de Microsoft de maintenir la parité entre les fonctions de langage dans les futures versions de C # et de VB.net. Je mettrais en avant mes arguments sur cette base.

http://www.chriseargle.com/post /2009/01/Parity-Between-Languages.aspx

En ce qui concerne la première question, s’il existait une déclaration publique, elle aurait probablement été placée quelque part sur le Web. Dans ce cas, Google devrait indiquer quelque chose (s’il existe).

S'il s'agit d'un courrier électronique direct avec l'équipe C #, il est plus que probable qu'il soit sous NDA. Par conséquent, il ne pourrait pas être publié de toute façon.

Avec la deuxième question, il existe une fonctionnalité de recherche sur Microsoft Connect qu’ils vous invitent à utiliser avant de saisir une nouvelle suggestion. Si vous ne le trouvez pas, il n’en existe probablement pas.

Ma recommandation serait de faire une suggestion, puis de la promouvoir pour que les autres en discutent.

D'après ce que je comprends, au moment de la modification, les gestionnaires des fonctions internes sont exécutés et c'est ce qui crée des problèmes pour vous.

Mais supposons que vous disposiez d’un filtre d’exception qui laisse passer l’exception sans la renvoyer réellement. Vous devrez toujours vous en occuper quelque part, et vous rencontrerez les mêmes types de problèmes (enfin d’effets).

Donc, à moins que je ne comprenne mal quelque chose, il n’est pas très rentable d’avoir des filtres d’exception pris en charge par la langue.

Je peux penser à au moins deux raisons pour lesquelles le filtrage des exceptions est absent de C #

  1. Autoriser les filtres d'exception peut encourager les programmeurs à effectuer des opérations dangereuses lors de la gestion des exceptions de premier passage à ce moment-là, même si ces opérations peuvent être effectuées en toute sécurité avec un "crochet" ou un "enfin". Par exemple, si le code figurant dans le champ "essayer". block acquiert un verrou et lève une exception tant que le verrou est maintenu, le verrou sera maintenu pendant l'exécution des filtres d'exception externes, mais sera libéré avant une "capture" externe. ou "finalement" le bloc est exécuté. En outre, au moins la dernière fois que j'ai vérifié, les exceptions qui se produisaient dans un filtre d'exception et qui n'étaient pas détectées dans celui-ci étaient silencieusement étouffées - ce qui constituait une situation laide.
  2. Les développeurs de C # ont pour vision de rendre leur langage "agnostique". Si C # prenait en charge le filtrage des exceptions de premier passage .net, les programmes utilisant cette fonctionnalité pourraient ne pas être utilisables sur les infrastructures qui gèrent les exceptions différemment. C'est la même raison pour laquelle C # interdit aux programmes de remplacer `Object.Finalize ()`. Bien que le raisonnement entourant `Object.Finalize ()` soit erroné (l’utilisation correcte de destructeurs nécessite l’utilisation d’autres méthodes spécifiques à la plate-forme, de sorte que l’utilisation de la syntaxe de destructeur pour `Object.Finalize ()` n’accomplit que pour encourager l’écriture de logiciel défectueux), le raisonnement a du sens en ce qui concerne les filtres d’exception. D'autre part, la meilleure façon de traiter ce problème serait d'exposer certaines fonctionnalités liées aux filtres d'exception, même si l'une d'elles n'exposait pas directement les filtres d'exception.

Une fonctionnalité que j'aimerais vraiment voir dans C # et vb, qui nécessiterait l’utilisation de filtres d’exception à implémenter mais qui ne nécessiterait pas de les exposer directement, serait un paramètre facultatif Exception pour un bloc enfin . Ce paramètre serait null si aucune exception non capturée ne se produit; sinon, il s'agirait de l'exception en question. Cela permettrait aux programmes dans lesquels un programme voudra faire quelque chose lorsqu'une exception se produit, mais pas réellement "gérer". il. Dans la plupart des cas, le paramètre Exception ne serait utilisé que pour vérifier null (ce qui signifie que la fonctionnalité serait équivalente à l'exposition de faute . blocs), mais cela offrirait des avantages dans les cas où une exception survient pendant le nettoyage. Actuellement, si une exception se produit pendant un bloc finally , il est nécessaire d'étouffer l'exception de blocage finally ou de remplacer celle qui existait déjà. Disposer de l’exception précédente dans le code de bloc finally permettrait de l’envelopper ou de le consigner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top