Rilevazione del compilatore automatico dell'aggiunta della stessa istanza dell'oggetto a un contenitore in un ciclo

StackOverflow https://stackoverflow.com/questions/1465486

Domanda

Questo è un errore stupido:

List<Foo> fooList = new List<Foo>();
Foo f = new Foo();
while (something.Read()) {
    f.Fill(something.GetRecord());
    fooList.Add(f);
}

Certo, dovrei istanziare un nuovo foo all'interno del ciclo.

Un compilatore può rilevare questo tipo di errore al momento della compilazione?

Agli occhi ingenui sembra che dovrebbe essere in grado di rilevare questo comportamento (riempire un elenco con istanze dello stesso oggetto in un ciclo). Dovrebbe quindi emettere un avvertimento come "stai riempiendo un contenitore con la stessa istanza più di una volta".

Allora, quanto sono ingenuo? Conosci una lingua in cui esiste qualcosa del genere?

È stato utile?

Soluzione

Sì, questo è possibile.

Tuttavia, non credo che uno strumento o un compilatore avverterebbe di questo stesso, quindi dovresti usare uno strumento che può essere esteso con le tue analisi. Per Java, Findbugs è un tale strumento. Per c, c ++, ecc. GCC 4.5 consentirà i plugin per le persone per scrivere le proprie estensioni e clangore Da LLVM è progettato anche per questo. C'è anche Deidra Da Mozilla, di nuovo per C ++. Per le lingue MS, c'è il Framework Phoenix.

Quindi la domanda è: come scrivi questa analisi? È un po 'più complicato e dipende dallo strumento. Ma fondamentalmente:

  • È possibile rilevare i loop abbastanza facilmente (cerca "componenti fortemente collegati"),
  • L'analisi alias può dirti se una particolare variabile o parametro si riferisce a un solo oggetto o a molti oggetti (cerca "oggetti astratti", forse),
  • È possibile trovare il contenitore giusto usando il tipo statico di un oggetto o variabile.

Quindi potresti facilmente rilevare una chiamata a List<>.append(x) In un ciclo, dove X può fare riferimento a un solo oggetto.

Altri suggerimenti

Cosa succede se vuoi riempire un elenco <> con più istanze di un oggetto? Avresti bisogno di decorare il tuo codice con #pragma Quindi il compilatore ti lascia solo?

Come dichiareresti anche una classe di avere questo tipo di restrizioni? Elenco <> non è davvero altro che una classe C#, puoi decompilare MSCorlib.dll e vedere la sua piena implementazione. Quindi, per avere questo tipo di conoscenza, dovrebbe essere codificato da qualche parte. Attributi? Sarebbe incredibilmente limitato. Metodi speciali per convalidare il tuo codice? Aggiungerebbe sovraccarico ai tuoi oggetti.

Questo tipo di cose non è mai (e non intendo mai) usato per un motivo: il numero estremamente piccolo di casi in cui aiuterebbe piuttosto che ostacolare non si avvicina in nessun luogo vicino a superare il costo molto reale che richiederebbe in entrambe le difficoltà di implementazione (del Framework stesso e del tuo codice) e colpi di prestazioni (da oggetti sovraccarichi che devono essere spostati attorno alla memoria mentre il GC fa le sue cose).

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