Domanda

Questo mi esorta davvero, quindi spero che qualcuno possa darmi una giustificazione ragionevole del perché le cose sono come sono.

NotImplementedException. Mi stai prendendo in giro, vero?

No, non ho intenzione di prenderlo a pugni economici dicendo: "Aspetta, il metodo è implementato - genera un'eccezione NotImplemented." Sì, è vero, devi implementare il metodo per lanciare NotImplementedException (a differenza di una pura chiamata di funzione virtuale in C ++ - ora ha senso!). Anche se è dannatamente divertente, c'è un problema più serio nella mia mente.

Mi chiedo solo, in presenza di NotImplementedException, come si può fare qualcosa con .Net? Dovresti racchiudere ogni chiamata di metodo astratta con un blocco try catch per evitare metodi che potrebbero non essere implementati? Se cogli un'eccezione del genere, cosa diavolo dovresti farci ??

Non vedo alcun modo per testare se un metodo è effettivamente implementato senza chiamarlo. Dal momento che chiamarlo può avere effetti collaterali, non posso fare tutti i miei controlli in anticipo e quindi eseguire il mio algoritmo. Devo eseguire il mio algoritmo, rilevare NotImplementedExceptions e alcuni come ripristinare la mia applicazione in uno stato sano.

È pazzo. Pazzo. Insane. Quindi la domanda è: Perché esiste NotImplementedException ?

Come attacco preventivo, non voglio che nessuno risponda, "poiché i progettisti devono inserire questo nel codice generato automaticamente." Questo è orribile. Preferirei che il codice generato automaticamente non venga compilato fino a quando non fornisci un'implementazione. Ad esempio, l'implementazione generata automaticamente potrebbe essere " throw NotImplementedException; " dove NotImplementedException non è definito!

Qualcuno ha mai catturato e gestito una NotImplementedException? Hai mai lasciato un'eccezione NotImplemented nel tuo codice? In tal caso, ciò rappresentava una bomba a tempo (cioè, l'hai lasciata lì per caso) o un difetto di progettazione (il metodo non dovrebbe essere implementato e non verrà mai chiamato)?

Sono anche molto sospettoso di NotSupportedException ... Non supportato? Cosa? Se non è supportato, perché fa parte della tua interfaccia? Qualcuno di Microsoft può sillabare eredità impropria? Ma potrei fare un'altra domanda per questo se non ricevo troppi abusi per questo.

Informazioni aggiuntive:

Questo è una lettura interessante sull'argomento.

Sembra esserci un forte accordo con Brad Abrams that " NotImplementedException è per funzionalità che non è ancora stata ancora implementata, ma dovrebbe (e sarà) realmente. Qualcosa di simile a ciò che potresti iniziare quando stai costruendo una classe, ottenere tutti i metodi lì lanciando NotImplementedException, quindi scaricarli con il codice reale & # 8230; "

Commenti da Jared Parsons sono molto deboli e probabilmente dovrebbero essere ignorati: NotImplementedException: genera questa eccezione quando un tipo non implementa un metodo per nessun altro motivo.

MSDN è ancora più debole sull'argomento, semplicemente affermando che " L'eccezione che viene generata quando non viene implementato un metodo o un'operazione richiesti. "

È stato utile?

Soluzione

C'è una situazione che trovo utile: TDD.

Scrivo i miei test, quindi creo gli stub in modo che i test vengano compilati. Quegli stub non fanno altro che lanciare new NotImplementedException (); . In questo modo i test falliranno di default, non importa quale. Se avessi usato un valore di ritorno fittizio, potrebbe generare falsi positivi. Ora che tutti i test vengono compilati e falliti perché non c'è implementazione, affronterò questi stub.

Dato che non uso mai un NotImplementedException in nessun'altra situazione, nessun NotImplementedException non passerà mai al codice di rilascio, poiché fallirà sempre alcuni test.

Non è necessario prenderlo dappertutto. Le buone API documentano le eccezioni generate. Questi sono quelli che dovresti cercare.

EDIT: ho scritto una regola FxCop per trovarli.

Questo è il codice:

using System;
using Microsoft.FxCop.Sdk;

/// <summary>
/// An FxCop rule to ensure no <see cref="NotImplementedException"/> is
/// left behind on production code.
/// </summary>
internal class DoNotRaiseNotImplementedException : BaseIntrospectionRule
{
    private TypeNode _notImplementedException;
    private Member _currentMember;

    public DoNotRaiseNotImplementedException()
        : base("DoNotRaiseNotImplementedException",
               // The following string must be the assembly name (here
               // Bevonn.CodeAnalysis) followed by a dot and then the
               // metadata file name without the xml extension (here
               // DesignRules). See the note at the end for more details.
               "Bevonn.CodeAnalysis.DesignRules",
               typeof (DoNotRaiseNotImplementedException).Assembly) { }

    public override void BeforeAnalysis()
    {
        base.BeforeAnalysis();
        _notImplementedException = FrameworkAssemblies.Mscorlib.GetType(
            Identifier.For("System"),
            Identifier.For("NotImplementedException"));
    }

    public override ProblemCollection Check(Member member)
    {
        var method = member as Method;
        if (method != null)
        {
            _currentMember = member;
            VisitStatements(method.Body.Statements);
        }
        return Problems;
    }

    public override void VisitThrow(ThrowNode throwInstruction)
    {
        if (throwInstruction.Expression != null &&
            throwInstruction.Expression.Type.IsAssignableTo(_notImplementedException))
        {
            var problem = new Problem(
                GetResolution(),
                throwInstruction.SourceContext,
                _currentMember.Name.Name);
            Problems.Add(problem);
        }
    }
}

E questi sono i metadati della regola:

<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="Bevonn Design Rules">
  <Rule TypeName="DoNotRaiseNotImplementedException" Category="Bevonn.Design" CheckId="BCA0001">
    <Name>Do not raise NotImplementedException</Name>
    <Description>NotImplementedException should not be used in production code.</Description>
    <Url>http://stackoverflow.com/questions/410719/notimplementedexception-are-they-kidding-me</Url>
    <Resolution>Implement the method or property accessor.</Resolution>
    <MessageLevel Certainty="100">CriticalError</MessageLevel>
    <Email></Email>
    <FixCategories>NonBreaking</FixCategories>
    <Owner></Owner>
  </Rule>
</Rules>

Per creare questo è necessario:

  • riferimento Microsoft.FxCop.Sdk.dll e Microsoft.Cci.dll

  • Inserisci i metadati in un file chiamato DesignRules.xml e aggiungilo come risorsa incorporata al tuo assembly

  • Assegna un nome all'assembly Bevonn.CodeAnalysis . Se si desidera utilizzare nomi diversi per i metadati o i file assembly, assicurarsi di modificare di conseguenza il secondo parametro nel costruttore di base.

Quindi aggiungi semplicemente l'assembly risultante alle tue regole FxCop ed elimina quelle dannate eccezioni dal tuo prezioso codice. Ci sono alcuni casi angolari in cui non viene segnalato un NotImplementedException quando ne viene lanciato uno, ma penso davvero che tu sia senza speranza se in realtà stai scrivendo un codice cthulhiano. Per usi normali, ovvero lancia nuovi NotImplementedException (); , funziona e questo è tutto ciò che conta.

Altri suggerimenti

È lì per supportare un caso d'uso abbastanza comune, un'API funzionante ma solo parzialmente completata. Di 'che voglio che gli sviluppatori testino e valutino la mia API - WashDishes () funziona, almeno sulla mia macchina, ma non sono ancora riuscito a codificare DryDishes () , figuriamoci PutAwayDishes () . Piuttosto che fallire silenziosamente, o dare qualche messaggio di errore criptico, posso essere abbastanza chiaro sul perché DryDishes () non funziona - non l'ho ancora implementato.

La sua eccezione sorella NotSupportedException ha senso soprattutto per i modelli di provider. Molte lavastoviglie hanno una funzione di asciugatura, quindi appartiene all'interfaccia, ma la mia lavastoviglie scontata non la supporta. Posso far sapere che tramite NotSupportedException

Riassumerò le mie opinioni su questo in un unico posto, poiché sono sparse in alcuni commenti:

  1. Si utilizza NotImplementedException per indicare che un membro dell'interfaccia non è ancora implementato, ma lo sarà. Questo si combina con test di unità automatizzati o test di QA per identificare le funzionalità che devono ancora essere implementate.

  2. Una volta implementata la funzione, si rimuove NotImplementedException . I nuovi test unitari sono scritti per la funzionalità per garantire che funzioni correttamente.

  3. NotSupportedException viene generalmente utilizzato per i provider che non supportano funzionalità che non hanno senso per tipi specifici. In questi casi, i tipi specifici generano l'eccezione, i client li catturano e li gestiscono nel modo appropriato.

  4. Il motivo per cui NotImplementedException e NotSupportedException esistono nel Framework è semplice: le situazioni che li portano sono comuni, quindi ha senso definirle nel Framework, in modo che gli sviluppatori non debbano continuare a ridefinirli. Inoltre, rende facile per i clienti sapere quale eccezione catturare (specialmente nel contesto di un unit test). Se devi definire la tua eccezione, devono capire quale eccezione catturare, che è almeno una perdita di tempo controproducente e spesso errata.

  

Perché NotImplementedException   esistere?

NotImplementedException è un ottimo modo per dire che qualcosa non è ancora pronto. Perché non è pronto è una domanda separata per gli autori del metodo. Nel codice di produzione è improbabile che tu rilevi questa eccezione, ma se lo facessi puoi immediatamente vedere cosa è successo ed è molto meglio che cercare di capire perché i metodi sono stati chiamati ma non è successo niente o peggio ancora - ricevi un po 'di "temporaneo"; risultato e ottieni " divertente " effetti collaterali.

  

Is NotImplementedException C #   equivalente di Java   UnsupportedOperationException?

No, .NET ha NotSupportedException

  

Devo eseguire il mio algoritmo, cattura   NotImplementedExceptions e alcuni   come ripristinare la mia applicazione ad alcuni   stato sano

Una buona API ha una documentazione sui metodi XML che descrive possibili eccezioni.

  

Sono molto diffidente nei confronti di   NotSupportedException anche ... No   supportato? Cosa? Se non lo è   supportato, perché fa parte del tuo   Interfaccia?

Possono esserci milioni di motivi. Ad esempio, è possibile introdurre una nuova versione dell'API e non voler / non supportare i vecchi metodi. Ancora una volta, è molto meglio vedere un'eccezione descrittiva piuttosto che scavare nella documentazione o eseguire il debug di codice di terze parti.

L'uso principale di un'eccezione NotImplementedException è nel codice stub generato: in questo modo non dimenticare di implementarlo !! Ad esempio, Visual Studio implementerà esplicitamente i metodi / le proprietà di un'interfaccia con il corpo che genera NotImplementedException.

Re NotImplementedException - questo serve a pochi usi; fornisce un'unica eccezione a cui (ad esempio) i test unitari possono agganciarsi per lavori incompleti. Ma fa anche quello che dice: semplicemente non c'è (ancora). Ad esempio, " mono " lancia questo dappertutto per i metodi che esistono nelle librerie MS, ma non sono ancora stati scritti.

Ri NotSupportedException - non tutto è disponibile. Ad esempio, molte interfacce supportano una coppia " puoi farlo? & Quot; / "fai questo". Se il " puoi farlo? & Quot; restituisce false, è perfettamente ragionevole per il "fare questo" per lanciare NotSupportedException . Esempi potrebbero essere IBindingList.SupportsSearching / IBindingList.Find () ecc.

La maggior parte degli sviluppatori Microsoft ha familiarità con i modelli di progettazione in cui una NotImplementedException è appropriata. In realtà è abbastanza comune.

Un buon esempio è un Pattern composito , in cui molti oggetti possono essere trattati come un singolo istanza di un oggetto. Un componente viene utilizzato come classe astratta di base per le classi foglia (correttamente) ereditate. Ad esempio, una classe di file e directory può ereditare dalla stessa classe di base astratta, poiché sono tipi molto simili. In questo modo, possono essere trattati come un singolo oggetto (il che ha senso quando si pensa a quali file e directory si trovano, ad esempio in Unix tutto è un file).

Quindi, in questo esempio, ci sarebbe un metodo GetFiles () per la classe Directory, tuttavia, la classe File non implementerebbe questo metodo, perché non ha senso farlo. Invece, ottieni NotImplementedException, perché un file non ha figli come una directory.

Nota che questo non è limitato a .NET: troverai questo schema in molte lingue e piattaforme OO.

Perché senti il ??bisogno di cogliere ogni possibile eccezione? Concludete anche ogni chiamata di metodo con catch (NullReferenceException ex) ?

Il lancio di codice stub NotImplementedException è un segnaposto, se lo fa rilasciare dovrebbe essere un bug proprio come NullReferenceException .

Penso che ci siano molte ragioni per cui MS ha aggiunto NotImplementedException al framework:

  • Per comodità; dal momento che molti sviluppatori ne avranno bisogno durante lo sviluppo, perché tutti dovrebbero farlo da soli?
  • In modo che gli strumenti possano contare sulla sua presenza; ad esempio, "Studio Implement Interface" di Visual Studio comando genera metodi stub che generano NotImplementedException. Se non fosse nel framework, ciò non sarebbe possibile, o almeno piuttosto imbarazzante (ad esempio, potrebbe generare codice che non può essere compilato fino a quando non aggiungi la tua NotImplementedException)
  • Incoraggiare una pratica standard "coerente"

Frankodwyer considera NotImplementedException come una potenziale bomba a orologeria. Direi che qualsiasi codice incompiuto è un timebomb, ma NotImplementedException è molto più facile da disarmare rispetto alle alternative. Ad esempio, è possibile fare in modo che il proprio server di build esegua la scansione del codice sorgente per tutti gli usi di questa classe e li segnali come avvisi. Se vuoi davvero vietarlo, potresti persino aggiungere un hook pre-commit al tuo sistema di controllo del codice sorgente che impedisce il check-in di tale codice.

Certo, se tiri la tua NotImplementedException, puoi rimuoverla dalla build finale per assicurarti che non rimangano bombe a tempo. Questo funzionerà solo se usi la tua implementazione in modo coerente nell'intero team e devi assicurarti di non dimenticare di rimuoverla prima di rilasciarla. Inoltre, potresti scoprire di non poterlo rimuovere; forse ci sono alcuni usi accettabili, ad esempio nel test del codice che non viene spedito ai clienti.

Non c'è davvero alcun motivo per catturare in realtà una NotImplementedException. Quando colpito, dovrebbe uccidere la tua app e farlo in modo molto doloroso. L'unico modo per risolverlo non è catturarlo, ma modificando il codice sorgente (implementando il metodo chiamato o modificando il codice chiamante).

Due motivi:

  1. I metodi vengono eliminati durante lo sviluppo e generano l'eccezione per ricordare agli sviluppatori che la loro scrittura del codice non è terminata.

  2. Implementazione di un'interfaccia di sottoclasse che, in base alla progettazione, non implementa uno o più metodi della classe o dell'interfaccia di base ereditata. (Alcune interfacce sono troppo generiche.)

Mi sembra un potenziale campo minato. In un lontano passato una volta ho lavorato su un sistema di rete legacy che era in esecuzione senza sosta da anni e che è caduto per un giorno. Quando abbiamo rintracciato il problema, abbiamo trovato del codice che chiaramente non era stato completato e che non avrebbe mai potuto funzionare - letteralmente, come il programmatore si è interrotto durante la codifica. Era ovvio che questo particolare percorso del codice non era mai stato preso prima.

La legge di Murphy afferma che qualcosa di simile sta solo supplicando di accadere nel caso di NotImplementedException. Concesso in questi giorni di TDD ecc., Dovrebbe essere raccolto prima del rilascio, e almeno puoi grep code per quell'eccezione prima del rilascio, ma comunque.

Durante i test è difficile garantire la copertura di tutti i casi, e questo sembra rendere il tuo lavoro più difficile rendendo problematiche di runtime di quelli che avrebbero potuto essere problemi di compilazione. (Penso che un simile tipo di "debito tecnico" provenga da sistemi che dipendono fortemente dalla "tipizzazione delle anatre", mentre riconosco che sono molto utili).

È necessaria questa eccezione per l'interoperabilità COM. È E_NOTIMPL . Il blog collegato mostra anche altri motivi

Lanciare NotImplementedException è il modo più logico per l'IDE di generare codice stub di compilazione. Come quando estendi l'interfaccia e fai in modo che Visual Studio la stub per te.

Se hai fatto un po 'di C ++ / COM, esisteva anche lì, tranne che era noto come E_NOTIMPL .

Esiste un caso d'uso valido per questo. Se stai lavorando su un metodo particolare di un'interfaccia, vuoi che il codice venga compilato in modo da poter eseguire il debug e testarlo. Secondo la tua logica, dovrai rimuovere il metodo dall'interfaccia e commentare il codice stub non compilante. Questo è un approccio molto fondamentalista e sebbene abbia dei meriti, non tutti lo faranno o dovrebbero aderire a questo. Inoltre, la maggior parte delle volte vuoi che l'interfaccia sia completa.

Avere NotImplementedException identifica bene quali metodi non sono ancora pronti, alla fine della giornata è facile come premere Ctrl + Shift + F per trovarli tutti, sono anche sicuro che codice statico lo prenderanno anche gli strumenti di analisi.

Non intendi spedire il codice con l'eccezione NotImplementedException . Se pensi che non utilizzandolo puoi migliorare il tuo codice, vai avanti, ma ci sono cose più produttive che puoi fare per migliorare la qualità del sorgente.

NotImplementedException

L'eccezione viene generata quando non viene implementato un metodo o un'operazione richiesti.

Rendere questa unica eccezione definita nel core .NET semplifica la ricerca e l'eliminazione. Se ogni sviluppatore dovesse creare il proprio ACME.EmaNymton.NotImplementedException sarebbe più difficile trovarli tutti.

NotSupportedException

L'eccezione viene generata quando un metodo invocato non è supportato.

Ad esempio quando si tenta di leggere, cercare o scrivere su uno stream che non supporta la funzionalità invocata.

Ad esempio gli iteratori generati (usando la parola chiave yield ) è un IEnumerator , ma il metodo IEnumerator.Reset genera NotSupportedException .

Da ECMA-335, la specifica CLI, in particolare i tipi di libreria CLI, System.NotImplementedException, sezione osservazioni:

" Un certo numero di tipi e costrutti, specificati altrove in questo standard, non sono richiesti per implementazioni CLI conformi solo al profilo del kernel. Ad esempio, il set di funzionalità in virgola mobile è costituito dai tipi di dati in virgola mobile System.Single e System.Double. Se il supporto per questi viene omesso da un'implementazione, qualsiasi tentativo di fare riferimento a una firma che include i tipi di dati in virgola mobile si traduce in un'eccezione del tipo System.NotImplementedException. & Quot;

Quindi, l'eccezione è intesa per implementazioni che implementano solo profili di conformità minimi. Il profilo minimo richiesto è il profilo del kernel (vedi ECMA-335 4a edizione - Partizione IV, sezione 3), che include il BCL, motivo per cui l'eccezione è inclusa nell'API principale e non in un'altra posizione.

L'uso dell'eccezione per indicare metodi stubbing o per metodi generati dal designer che mancano di implementazione significa fraintendere l'intento dell'eccezione.

Il motivo per cui queste informazioni NON sono incluse nella documentazione MSDN per l'implementazione della CLI da parte di MS è oltre me.

Non posso garantire NotImplementedException (per lo più concordo con la tua opinione) ma ho usato NotSupportedException ampiamente nella libreria principale che usiamo al lavoro. DatabaseController, ad esempio, consente di creare un database di qualsiasi tipo supportato, quindi utilizzare la classe DatabaseController per tutto il resto del codice senza preoccuparsi troppo del tipo di database sottostante. Roba abbastanza semplice, vero? Dove NotSupportedException è utile (e dove avrei usato la mia implementazione se non ne esistesse già una) sono due casi principali:

1) Migrazione di un'applicazione su un database diverso Si dice spesso che ciò accada raramente, se mai, o è necessario. Bullsh * t. Ottieni di più.

2) Stesso database, driver diverso L'esempio più recente di questo è stato quando un client che utilizza un'applicazione supportata da Access è stato aggiornato da WinXP a Win7 x64. Non essendo un driver JET a 64 bit, il loro ragazzo IT ha invece installato AccessDatabaseEngine. Quando la nostra app si è arrestata in modo anomalo, siamo riusciti a vedere facilmente dal registro che si trattava di DB.Connect che si arrestava in modo anomalo con NotSupportedException, che siamo riusciti a risolvere rapidamente. Un altro esempio recente è stato uno dei nostri programmatori che cercava di utilizzare le transazioni su un database di Access. Anche se Access supporta le transazioni, la nostra libreria non supporta le transazioni Access (per motivi che non rientrano nell'ambito di questo articolo). NotSupportedException, è il tuo momento di brillare!

3) Funzioni generiche Non riesco a pensare a una concisa "per esperienza" esempio qui, ma se pensi a qualcosa come una funzione che aggiunge un allegato a una e-mail, vuoi che sia in grado di prendere alcuni file comuni come JPEG, qualsiasi cosa derivata da varie classi di streaming e praticamente tutto ciò che ha un " ;. ToString " metodo. Per l'ultima parte, non puoi certamente tenere conto di ogni tipo possibile, quindi lo rendi generico. Quando un utente passa OurCrazyDataTypeForContainProprietarySpreadsheetData, usa la riflessione per verificare la presenza di un metodo ToString e restituisce NotSupportedException per indicare la mancanza di supporto per detti tipi di dati che non supportano ToString.

NotSupportedException non è affatto una caratteristica cruciale ma è qualcosa che mi ritrovo a usare molto di più mentre lavoro su progetti più grandi.

Supponiamo che tu abbia questo metodo nel tuo codice di produzione

public void DoSomething()

Quale sceglieresti se vuoi lasciarlo più tardi per finire?

public void DoSomething()
{
}

o

public void DoSomething()
{
    throw new NotImplementedException();
}

Vorrei certamente prendere il secondo. Abbinato a Elmah o qualsiasi altro meccanismo di registrazione degli errori che hai (implementato come aspetto nell'intera applicazione). Insieme al filtro registro / eccezione per attivare la notifica e-mail di errore critico quando viene rilevata.

L'argomento che NotImplementedException == incompiuto non è neanche corretto. (1) La cattura di metodi non implementati dovrebbe essere lasciata ai test unitari / ai test di integrazione. Se hai una copertura del 100% (cosa che dovresti fare ora, con così tanti strumenti di generazione di mock / stub / code) senza NotImplementedException, quali sono le tue preoccupazioni? (2) Generazione di codice. Semplicemente semplice. Ancora una volta, se generi il codice e utilizzo solo metà del codice generato, perché non dovrei avere NotImplementedException nel resto dello stub generato?

È come dire che il codice non dovrebbe essere compilato a meno che ogni input nullable debba essere controllato / gestito per null. (AKA l'errore di trilioni di dollari, se non di più). La lingua dovrebbe essere flessibile, mentre i test / i contratti dovrebbero essere solidi.

Raramente lo uso per il fissaggio dell'interfaccia. Supponi di avere un'interfaccia che devi rispettare ma che un determinato metodo non verrà mai chiamato da nessuno, quindi attacca un NotImplementedException e se qualcuno lo chiama saprà che stanno facendo qualcosa di sbagliato.

NotImplementedException viene generato per alcuni metodi di .NET (vedere il parser C # nel codice DOM che non è implementato, ma il metodo esiste!) Puoi verificare con questo metodo Microsoft.CSharp.CSharpCodeProvider.Parse

Sono entrambi hack per due problemi comuni.

NotImplementedException è una soluzione alternativa per gli sviluppatori che sono astronauti dell'architettura e amano scrivere prima l'API, poi il codice. Ovviamente, dal momento che questo non è un processo incrementale, non puoi implementare tutto in una volta e quindi vuoi far finta di essere semi-fatto lanciando NotImplementedException.

NotSupportedException è un trucco per la limitazione dei sistemi di tipo come quelli presenti in C # e Java. In questi sistemi di tipo, dici che un rettangolo "è un" forma se rettangolo eredita tutte le caratteristiche delle forme (incl. Funzioni membro + variabili). Tuttavia, in pratica, questo non è vero. Ad esempio, un quadrato è un rettangolo, ma un quadrato è una restrizione di un rettangolo, non una generalizzazione.

Quindi, quando si desidera ereditare e limitare il comportamento della classe genitore, si lancia NotSupported su metodi che non hanno senso per la restrizione.

Che dire di prototipi o progetti incompiuti?

Non credo sia una pessima idea usare un'eccezione (anche se in quel caso uso una finestra di messaggio).

Beh, sono abbastanza d'accordo. Se un'interfaccia è stata creata in modo tale che non tutte le classi possano implementarne tutti i bit, secondo me avrebbe dovuto essere suddivisa.

Se IList può o non può essere modificato, dovrebbe essere stato suddiviso in due, uno per la parte non modificabile (getter, ricerca, ecc.) e uno per la parte modificabile (setter, aggiungi, rimuovi, ecc. ).

Ho alcune NotImplementedExceptions nel mio codice. Spesso proviene da una parte di un'interfaccia o di una classe astratta. Alcuni metodi di cui potrei avere bisogno in futuro, hanno senso come parte della classe, ma non voglio prendere il tempo di aggiungere a meno che non ne abbia davvero bisogno. Ad esempio, ho un'interfaccia per tutti i singoli tipi di statistiche nel mio gioco. Uno di questi tipi è un ModStat, che è la somma delle statistiche di base più tutti i modificatori (cioè armi, armature, incantesimi). La mia interfaccia stat ha un evento OnChanged, ma il mio ModStat funziona calcolando la somma di tutte le statistiche a cui fa riferimento ogni volta che viene chiamata. Quindi, invece di avere l'overhead di una tonnellata di eventi ModStat.OnChange sollevati ogni volta che cambia una stat, ho solo lanciato NotImplementedException se qualcuno tenta di aggiungere / rimuovere un ascoltatore su OnChange.

I linguaggi .NET sono incentrati sulla produttività, quindi perché dedicare del tempo a scrivere codice che non utilizzerai nemmeno?

Ecco un esempio: in Java, ogni volta che si implementa l'interfaccia Iterator , è necessario sovrascrivere i metodi ovvi hasNext () e next () , ma esiste anche delete () . Nel 99% dei casi d'uso non ho bisogno di questo, quindi lancio semplicemente un NotImplementedException . È molto meglio che non fare nulla in silenzio.

NotImplementedException esiste solo per facilitare lo sviluppo. Immagina di iniziare a implementare un'interfaccia. Ti piacerebbe essere in grado di costruire almeno quando hai finito di implementare un metodo, prima di passare al successivo. Stubbing dei metodi NotImplemented con NotImplementedExceptions è un ottimo modo di vivere il codice incompiuto che è super facile da individuare in seguito. Altrimenti rischi di implementare rapidamente qualcosa che potresti dimenticare di risolvere.

Se non si desidera utilizzarlo, ignorarlo. Se hai un blocco di codice il cui successo dipende dal successo di ogni pezzo, ma potrebbe non riuscire nel mezzo, l'unica opzione è quella di catturare il Exception di base e ripristinare ciò che deve essere ripristinato . Dimentica NotImplementedException . Potrebbero esserci tonnellate di eccezioni, come MyRandomException e GtfoException e OmgLolException . Dopo aver originariamente scritto il codice che potrei trovare e lanciare UN ALTRO tipo di eccezione dall'API che stai chiamando. Uno che non esisteva quando hai scritto il tuo codice. Gestisci quelli che sai come gestire e ripristinare per tutti gli altri, ad esempio catch (Exception) . È piuttosto semplice, penso ... Trovo che sia utile. Soprattutto quando stai provando cose fantasiose con il linguaggio / quadro che a volte ti costringono a fare qualcosa.

Un esempio che ho è la serializzazione. Ho aggiunto proprietà nella mia libreria .NET che non esistono nel database (ad esempio, wrapper convenienti rispetto alle proprietà "stupide" esistenti, come una proprietà FullName che combina FirstName , MiddleName e LastName ). Quindi voglio serializzare questi tipi di dati su XML per inviarli via cavo (ad esempio, da un'applicazione ASP.NET a JavaScript), ma il framework di serializzazione serializza solo le proprietà pubbliche con get e < code> set accessori. Non voglio che tu sia in grado di impostare FullName perché allora dovrei analizzarlo e potrebbe esserci un formato imprevisto che analizzo erroneamente e l'integrità dei dati esce dalla finestra. È più semplice usare solo le proprietà sottostanti per questo, ma poiché la lingua e l'API mi richiedono un accessore set , lancerò un NotImplementedException (non lo ero a conoscenza di NotSupportedException fino a quando non leggo questo thread, ma uno dei due funziona) in modo che se un programmatore lungo la strada prova a impostare FullName incontrerà l'eccezione durante il test e realizzare il suo errore.

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