Pergunta

Nota: este não é uma duplicata de Jeff pergunta .

Essa pergunta "é um equivalente?" Eu sei que não é, e eu quero saber por que!

A razão que eu peço é que eu só acaba de se tornar claro sobre o quão importante é, ea conclusão parece muito estranho para mim.

O bloco de tratamento de exceção de Enterprise Library da Microsoft aconselha-nos a usar este padrão:

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

    // recover from x somehow
}

A política é definida em um arquivo XML, o que significa que, se um cliente tem um problema, podemos modificar a política para ajudar com rastreamento (ou talvez papering sobre) o problema para dar-lhes uma resolução rápida até que lidamos com ele corretamente - que pode envolver a discutir com 3 partes, sobre quem é a culpa toda é.

Este é basicamente um reconhecimento do simples fato de que em aplicações reais o número de tipos de exceção e seu status de "recuperação" é praticamente impossível de gerir sem uma instalação como esta.

Enquanto isso, a equipe de CLR na MS diz que isso não é uma opção, e não é que esses caras sabem o que estão falando! O problema é que a direita antes do bloco catch corridas, todos os blocos finally aninhados dentro do bloco try será executado. Então, esses blocos finally pode fazer qualquer um dos seguintes:

  • Inocentemente modificar o estado do programa (ufa, sorte).
  • Lixo algo importante em dados do cliente, porque o estado do programa é asneira em um grau desconhecido.
  • Disguise ou destruir provas importantes que precisamos para diagnosticar um problema -. Especialmente se estamos falando de chamadas em código nativo
  • Lance outro exceção, aumentando a confusão geral e miséria.

Note que a instrução using e C ++ / CLI destruidores são construídos sobre try / finally, por isso eles são muito afetados.

Então, claramente, o padrão catch / throw para exceções de filtragem não é bom. O que é realmente necessário é uma forma de exceções de filtro, através de uma política, sem realmente pegá-los e assim provocando a execução de blocos finally, a menos que encontrar uma política que nos diz a exceção é seguro para se recuperar.

A equipe de CLR blog sobre isso recentemente:

O resultado é que temos que escrever uma função auxiliar em VB.NET para nos permitir acessar esta capacidade vital de C #. A grande indício de que há um problema é que não há código no BCL que faz isso. Muitas pessoas têm um blog sobre a fazê-lo, mas eles raramente ou nunca mencionar a coisa sobre blocos try / finally, que é o assassino.

O que eu gostaria de saber é:

  • Existem quaisquer declarações públicas ou e-mails diretos pessoas receberam da equipe C # sobre este assunto?
  • Há alguma sugestão Microsoft Connect existentes pedindo isso? Ouvi rumores de-los, mas nenhuma das palavras-chave prováveis ??apareceu nada.

Update: como mencionado acima, eu já procurei no Microsoft Connect sem encontrar nada. Eu também tenho (sem surpresa) Googled. Eu só encontrei pessoas explicando por que eles precisam deste recurso , ou apontar o vantagens dele em VB.NET , ou inutilmente na esperança de que será adicionado em uma versão futura do C # , ou trabalhando em torno dela , e abundância de enganosa conselho . Mas nenhuma declaração sobre a justificativa para omiti-lo de todas as versões atuais do C #. E a razão pela qual eu estou perguntando sobre questões Ligue existentes é para que ( a) não criar um duplicado desnecessário e (b) eu posso dizer as pessoas interessadas se eu tiver que criar um.

Update 2: Encontrado um antigo blog interessante post de Eric Gunnerson , antigo membro da equipe de C #:

"Sim, ser capaz de colocar uma condição para um prendedor é um pouco mais conveniente de ter que escrever o teste -se, mas ele realmente não permitir -lo a fazer nada de novo ".

Essa foi a mesma suposição que eu tive até que foi devidamente explicado para mim!

Foi útil?

Solução

Como a quaisquer erros de conexão existentes. O seguinte problema lida com fliters de exceção. O usuário não afirmou explicitamente que queria ser um filtro real no sentido de quando executam mas IMHO é implícita pela lógica.

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

Além dessa questão, porém, não há problemas posso encontrar ou sabe de que estão relacionados ao que você está procurando. Eu acho que faria bom ter uma questão separada que chama explicitamente salientar a falta de filtros de exceção estilo VB.Net.

Eu não me preocuparia muito sobre a introdução de uma pergunta duplicado se você tiver feito um pouco de diligência à procura de um já existente. Se houver um joguete, Mads vai enganar-lo em conformidade e ligá-lo ao pedido principal.

Como para a parte de começar uma resposta oficial da equipe de C #, você provavelmente irá obter que quando você quer 1) envie um erro de conexão ou 2) obter enganados contra o bug principal. Eu realmente duvido que haja uma razão / justificativa oficial para fora lá agora.

Aqui está a minha especulação sobre a questão: Meu palpite é que esse recurso simplesmente não estava no conjunto original C função # 1.0 e desde então não houve demanda suficiente para fazê-lo na língua. A C # e equipe VB gastar uma quantidade enorme de recursos de linguagem tempo escalão no início de cada ciclo de navio. Nós temos que fazer alguns muito cortes difícil às vezes. Sem demanda suficiente há muito pouca chance de um recurso irá torná-la para a língua.

Até recentemente eu aposto que você seria duramente pressionado para encontrar uma em cada 10 pessoas que entenderam a diferença entre Tente de VB.Net / Quando e usando apenas uma planície antiga declaração se em um bloco catch C #. Parece ser um pouco mais sobre os povos mentes ultimamente, então talvez ele vai fazê-lo em uma versão futura do langauge.

Outras dicas

Usando exceção de filtro Inject pode ser mais simples do que usar a solução alternativa delegado.

Para uma verdadeira resposta para a sua pergunta que você vai precisar de uma resposta de Anders Hejlsberg, ou alguém que estava nas reuniões do projeto original. Você pode tentar ver se você pode obtê-lo solicitado pelo Canal 9 entrevistador próxima vez o C # equipa de design é entrevistado .

Eu acho que quando a decisão original foi feita, filtros de exceção eram vistos como uma complicação desnecessária que pode fazer mais mal do que bem. Você certamente pode ver o desejo de permanecer 'silenciosa' sobre os recursos não comprovados nesta entrevista sobre a decisão de não apoiar exceções verificadas: O problema com exceções verificadas .

Eu acho que os cenários de diagnóstico postmoterm argumentam fortemente para fornecer acesso a filtros de exceção na língua. No entanto esses cenários podem não ter sido articulada na época. Também esses cenários realmente precisam de apoio ferramental adequado, o que certamente não estava disponível em V1. Finalmente, pode haver grandes negativos sobre a adição deste recurso que não estamos considerando.

Se não houver um erro de conexão a este você deve digitar um e incentivar outras pessoas a votar-lo. [Eu recomendo pedir acesso ao recurso CLR em vez de tentar projetar como ele se encaixa na língua.]

Eu não acredito que o Java tem uma opção de filtro também. Supondo que se o fizesse, também veríamos um em C #. VB.net provavelmente tem um por acaso uma vez que a equipe VB começou com uma ardósia limpa.

Uma coisa que o trabalho poder em seu favor, tanto quanto ganhar esta opção em uma futura versão do C # é objetivo declarado da Microsoft para manter a paridade entre características laguage em futuras versões do C # e VB.net. Gostaria de apresentar meu argumento com base nisso.

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

Em relação à primeira pergunta, se houvesse uma declaração pública, então era mais do que provável put no lugar web, nesse caso, o Google deve transformar-se alguma coisa (se existir).

Se for um e-mail direto com a equipe C #, então é mais provável que ele está sob NDA, para que ele não seria capaz de ser publicado de qualquer maneira.

Com a segunda questão, não é um recurso de pesquisa no Microsoft Connect que pedir-lhe para usar antes de entrar em uma nova sugestão. Se você não consegue encontrá-lo, então provavelmente não há um.

A minha recomendação seria colocar uma sugestão, e então promovê-lo para obter outros a pesar sobre ele.

Como eu entendo eles, no momento da rethrow, os finalmente manipuladores nas funções internas são executados e que é o que cria problemas para você.

Mas vamos dizer que você tem um filtro de exceção que passa a exceção através sem realmente rethrowing-lo. Você ainda vai ter que lidar com isso de alguma forma, em algum lugar, e você vai correr nos mesmos tipos de problemas (finalmente efeitos) lá.

Assim, a menos que eu sou mal-entendido alguma coisa, não é grande ganho de ter filtros de exceção suportado idiomas.

Eu posso pensar em pelo menos duas razões pelas quais filtragem exceção está ausente do C #

  1. Permitir filtros de exceção pode encorajar programadores a fazer as coisas durante a manipulação de exceção de primeira passagem que seria inseguro naquela época, mesmo que poderia ser feito com segurança dentro de um 'catch' ou 'finalmente'. Por exemplo, se o código dentro do bloco "try" adquire um bloqueio e lança uma exceção enquanto o bloqueio é mantido, o bloqueio será realizada durante a execução de filtros de exceção exteriores, mas será lançado antes de um "catch" exterior ou "finalmente "bloco é executado. Além disso, pelo menos a última vez que verifiquei, exceções que ocorreram dentro de um filtro de exceção e não capturados dentro dele foram silêncio abafado - algo de uma situação feia.
  2. Os implementadores de C # tem uma visão de fazer a sua língua 'quadro agnóstico'. Se C # .net suportado filtragem exceção de primeira passagem, programas que usaram esse recurso pode ser inutilizado sobre os quadros quais exceções manuseada diferentemente. Esta é a mesma razão que o C # proíbe programas de substituir `Object.Finalize ()`. Enquanto o raciocínio em torno `Object.Finalize ()` é falho (uso correto dos destruidores requer o uso de outros métodos específicos da plataforma, de modo que requer o uso de sintaxe destruidor para `Object.Finalize ()` não leva a nada, exceto t77o incentivar a escrita de software defeituoso) o raciocínio faz algum sentido em relação a filtros de exceção. Por outro lado, a maneira correta de lidar com essa questão seria para expor algumas características-exceção de filtro relacionadas mesmo se não se expõem filtros de exceção diretamente.

Uma característica que eu realmente gostaria de ver em C # e VB, o que exigiria o uso de filtros de exceção de implementar, mas que não exigiria expondo-os diretamente, seria um parâmetro Exception opcional para um bloco finally. Este parâmetro seria null se não ocorrer nenhuma exceção não capturada; caso contrário ele iria realizar a excepção em causa. Isso permitiria que para situações em que um programa vai querer fazer algo quando ocorre uma exceção, mas na verdade não "pega-lo". Na maioria dos casos, o parâmetro Exception não seria usado para qualquer coisa, exceto para verificar se há null (ou seja, o recurso seria equivalente a expor blocos fault), mas seria oferecer vantagens nos casos em que ocorre uma exceção durante a limpeza. Atualmente, se ocorrer uma exceção durante um bloco finally, é necessário para abafar qualquer exceção finally-block ou substituir o pré-existente. Tendo a excepção anteriormente disponível para o código de bloco finally lhe permitiria qualquer envoltório ou registrá-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top