Domanda

Nota: questo non è un duplicato della domanda di Jeff .

Quella domanda posta " è un equivalente? " So che non c'è, e voglio sapere perché!

Il motivo per cui chiedo è che sono appena diventato chiaro su quanto sia importante e la conclusione mi sembra molto strana.

Il blocco Gestione eccezioni di Microsoft Enterprise Library ci consiglia di utilizzare questo modello:

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

    // recover from x somehow
}

La politica è definita in un file XML, quindi ciò significa che se un cliente ha un problema, possiamo modificare la politica per aiutare a rintracciare (o forse documentare) il problema per dare loro una rapida risoluzione fino a quando non ci occupiamo con esso correttamente, il che può comportare la discussione con terze parti, di chi sia la colpa.

Questo è fondamentalmente un riconoscimento del semplice fatto che nelle applicazioni reali il numero di tipi di eccezione e la loro "recuperabilità" lo stato è praticamente impossibile da gestire senza una struttura come questa.

Nel frattempo, il team CLR di MS afferma che questa non è un'opzione, e risulta che quei ragazzi sanno di cosa stanno parlando! Il problema è che prima dell'esecuzione del blocco catch , verranno eseguiti tutti i blocchi infine nidificati all'interno del blocco try . Quindi quei blocchi infine possono eseguire una delle seguenti operazioni:

  • Modifica in modo innocuo lo stato del programma (phew, lucky).
  • Cestino di qualcosa di importante nei dati del cliente, perché lo stato del programma è rovinato a un livello sconosciuto.
  • mascherare o distruggere prove importanti che dobbiamo diagnosticare un problema, specialmente se stiamo parlando di chiamate in codice nativo.
  • Lancia un'altra eccezione, aggiungendo alla confusione generale e alla miseria.

Nota che l'istruzione using e i distruttori C ++ / CLI sono basati su try / infine , quindi sono interessati anche loro.

Quindi chiaramente il modello catch / lancio per filtrare le eccezioni non va bene. Ciò che è effettivamente necessario è un modo per filtrare le eccezioni, tramite una politica, senza effettivamente catturarle e quindi innescare l'esecuzione dei blocchi infine , a meno che non troviamo una politica che ci dice che l'eccezione è sicura da cui recuperare .

Di recente il team CLR ha scritto questo blog:

Il risultato è che dobbiamo scrivere una funzione di supporto in VB.NET per consentirci di accedere a questa funzionalità vitale da C #. Il grande indizio che c'è un problema è che c'è del codice nel BCL che lo fa. Molte persone hanno scritto sul blog di farlo, ma raramente menzionano raramente i blocchi try / infine , che è l'assassino.

Quello che vorrei sapere è:

  • Ci sono dichiarazioni pubbliche o e-mail dirette che le persone hanno ricevuto dal team C # su questo argomento?
  • Esistono suggerimenti di Microsoft Connect esistenti che lo richiedono? Ne ho sentito delle voci, ma nessuna delle probabili parole chiave ha rivelato nulla.

Aggiornamento: come indicato sopra, ho già cercato su Microsoft Connect senza trovare nulla. Ho anche (ovviamente) cercato su Google. Ho trovato solo persone spiegando perché hanno bisogno di questa funzione o sottolineando i vantaggi in VB.NET o sperando inutilmente che sia aggiunto in una versione futura di C # o aggirandolo , e un sacco di consigli fuorvianti . Ma nessuna dichiarazione sulla logica per ometterla da tutte le versioni correnti di C #. E la ragione per cui sto chiedendo dei problemi esistenti di Connect è che (a) non creo un duplicato non necessario e (b) posso dire agli interessati se devo crearne uno.

Aggiornamento 2: trovato un interessante post sul blog di Eric Gunnerson , precedentemente del team C #:

  

" Sì, essendo in grado di impostare una condizione   una cattura è un po 'più conveniente   che dover scrivere il test   te stesso, ma non lo abilita davvero   di fare qualcosa di nuovo. "

Era lo stesso presupposto che ho avuto fino a quando non mi è stato adeguatamente spiegato!

È stato utile?

Soluzione

Per quanto riguarda eventuali bug di connessione esistenti. Il seguente problema riguarda i fliter di eccezione. L'utente non ha dichiarato esplicitamente che voleva che fossero un vero filtro nel senso di quando vengono eseguiti, ma IMHO è implicito dalla logica.

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

Oltre a questo problema, tuttavia, non ci sono problemi che posso trovare o conoscere che siano correlati a ciò che stai cercando. Penso che farebbe bene avere un problema separato che esplicitamente evoca la necessità di filtri di eccezione in stile VB.Net.

Non mi preoccuperei troppo di introdurre una domanda duplicata se hai fatto un po 'di dovuta diligenza cercando una esistente. Se esiste un duplicato, Mads lo duplica di conseguenza e ti collega alla richiesta principale.

Per quanto riguarda la parte relativa all'ottenimento di una risposta ufficiale da parte del team di C #, si otterrà probabilmente che quando si 1) presenta un bug di connessione o 2) viene duplicato rispetto al bug principale. Dubito davvero che ci sia una ragione / giustificazione ufficiale là fuori in questo momento.

Ecco la mia speculazione sul problema: la mia ipotesi è che questa funzione non fosse semplicemente sul set di funzionalità C # 1.0 originale e da quel momento non c'è stata abbastanza richiesta per entrare nel linguaggio. Il team di C # e VB impiega un'incredibile quantità di tempo a classificare le funzionalità del linguaggio all'inizio di ogni ciclo di spedizione. A volte dobbiamo fare alcuni tagli molto difficili. Senza una domanda sufficiente, ci sono poche possibilità che una funzionalità riesca a entrare nella lingua.

Fino a poco tempo fa scommettevo che sarebbe difficile trovare 1 persona su 10 che capisse la differenza tra Try / When di VB.Net e usare semplicemente una vecchia istruzione if in un blocco catch C #. Sembra essere un po 'più nella mente delle persone ultimamente, quindi forse lo trasformerà in una versione futura della lingua.

Altri suggerimenti

L'uso di Iniezione filtro eccezioni può essere più semplice rispetto all'utilizzo della soluzione alternativa delegata.

Per una vera risposta alla tua domanda avrai bisogno di una risposta da Anders Hejlsberg, o da qualcuno che stava partecipando alle riunioni di design originali. Potresti provare a vedere se riesci a ottenere la domanda dall'intervistatore di Channel 9 la prossima volta viene intervistato il team di progettazione di C # .

Immagino che quando fu presa la decisione originale, i filtri delle eccezioni erano visti come una complicazione non necessaria che poteva fare più male che bene. Puoi certamente vedere il desiderio di rimanere "silenzioso" su funzionalità non dimostrate in questa intervista sulla decisione di non supportare le eccezioni verificate: Il problema con le eccezioni verificate .

Penso che gli scenari diagnostici postmoterm sostengano fortemente di fornire l'accesso ai filtri delle eccezioni nella lingua. Tuttavia, quegli scenari potrebbero non essere stati articolati al momento. Anche quegli scenari necessitano davvero di un adeguato supporto degli strumenti, che certamente non era disponibile in V1. Infine potrebbero esserci grossi aspetti negativi sull'aggiunta di questa funzione che non stiamo prendendo in considerazione.

Se non è presente un bug di connessione, dovresti inserirne uno e incoraggiare gli altri a votarlo. [Consiglierei di chiedere l'accesso alla funzione CLR piuttosto che tentare di progettare come si adatta alla lingua.]

Non credo nemmeno che Java abbia un'opzione di filtro. Indovinando che se lo facesse, ne vedremmo anche uno in C #. VB.net probabilmente ne ha uno per caso dato che il team VB ha iniziato con una lavagna pulita.

Una cosa che potrebbe funzionare a tuo favore fino a ottenere questa opzione in una versione futura di C # è l'obiettivo dichiarato di Microsoft di mantenere la parità tra le funzionalità di lingua nelle versioni future di C # e VB.net. Vorrei avanzare la mia argomentazione basata su quello.

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

Per quanto riguarda la prima domanda, se c'era una dichiarazione pubblica, allora è stata più che probabile messa sul web da qualche parte, nel qual caso, Google dovrebbe presentare qualcosa (se esiste).

Se si tratta di un'e-mail diretta con il team C #, è più che probabile che sia sotto NDA, quindi non potrebbe essere pubblicato comunque.

Con la seconda domanda, esiste una funzionalità di ricerca su Microsoft Connect che ti viene chiesto di utilizzare prima di inserire un nuovo suggerimento. Se non riesci a trovarlo, probabilmente non ce n'è uno.

La mia raccomandazione sarebbe quella di inserire un suggerimento e quindi promuoverlo per indurre gli altri a valutarlo.

A quanto ho capito, al momento del riprogrammamento, gli handler infine nelle funzioni interne vengono eseguiti e questo è ciò che crea problemi per te.

Ma supponiamo che tu abbia un filtro delle eccezioni che passa l'eccezione senza in realtà ridisegnarla. Dovrai comunque gestirlo in qualche modo da qualche parte, e incontrerai gli stessi tipi di problemi (finalmente effetti) lì.

Quindi, a meno che non stia fraintendendo qualcosa, non c'è grande vantaggio dall'avere filtri di eccezione supportati dalla lingua.

Mi vengono in mente almeno due motivi per cui il filtro delle eccezioni è assente da C #

  1. Consentire i filtri delle eccezioni potrebbe incoraggiare i programmatori a fare cose durante la gestione delle eccezioni di primo passaggio che non sarebbero sicure in quel momento, anche se potrebbero essere eseguite in sicurezza in un "catch" o "finalmente". Ad esempio, se il codice all'interno di " prova " il blocco acquisisce un blocco e genera un'eccezione mentre il blocco viene mantenuto, il blocco verrà trattenuto durante l'esecuzione dei filtri di eccezione esterni, ma verrà rilasciato prima di un "catch" esterno o "finalmente" il blocco viene eseguito. Inoltre, almeno l'ultima volta che ho controllato, le eccezioni che si sono verificate all'interno di un filtro di eccezioni e non sono state catturate al suo interno sono state silenziosamente soffocate - una situazione brutta.
  2. Gli implementatori di C # hanno la visione di rendere il loro linguaggio "agnostico". Se C # supportava il filtro delle eccezioni di primo passaggio .net, i programmi che utilizzavano quella funzionalità potrebbero essere inutilizzabili su framework che gestiscono le eccezioni in modo diverso. Questo è lo stesso motivo per cui C # proibisce ai programmi di sovrascrivere `Object.Finalize ()`. Mentre il ragionamento che circonda `Object.Finalize ()` è errato (l'uso corretto dei distruttori richiede l'uso di altri metodi specifici della piattaforma, quindi richiedere l'uso della sintassi del distruttore per `Object.Finalize ()` non compie nulla tranne che per incoraggiare la scrittura di software difettoso) il ragionamento ha un senso per quanto riguarda i filtri delle eccezioni. D'altra parte, il modo corretto di affrontare tale problema sarebbe quello di esporre alcune funzionalità relative al filtro delle eccezioni anche se non si esponessero direttamente i filtri delle eccezioni.

Una caratteristica che mi piacerebbe davvero vedere in C # e vb, che richiederebbe l'uso di filtri di eccezione da implementare ma che non richiederebbe di esporli direttamente, sarebbe un parametro opzionale Exception per un blocco finalmente . Questo parametro sarebbe null se non si verifica alcuna eccezione non rilevata; altrimenti si tratterebbe dell'eccezione in questione. Ciò consentirebbe situazioni in cui un programma vorrà fare qualcosa quando si verifica un'eccezione, ma in realtà non "gestisce". esso. Nella maggior parte dei casi, il parametro Exception non verrebbe utilizzato per nulla tranne che per controllare null (il che significa che la funzione sarebbe equivalente all'esposizione di fault blocchi), ma offrirebbe vantaggi nei casi in cui si verifica un'eccezione durante la pulizia. Attualmente, se si verifica un'eccezione durante un blocco finally , è necessario soffocare l'eccezione di blocco finally o sovrascrivere quella preesistente. La disponibilità dell'eccezione precedente al codice di blocco finalmente consentirebbe di racchiuderlo o registrarlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top