2014-10-24 10 views
13

Dato il seguente codice, ReSharper sarà correttamente mi avvisate su una possibile NullReferenceException su foo.Bar perché ci potrebbero essere elementi nulli nella enumerabile:Come faccio a dire a Resharper che il mio metodo IEnumerable rimuove i null?

IEnumerable<Foo> foos = GetFoos(); 
var bars = foos.Select(foo => foo.Bar); 

Un modo per soddisfare l'analizzatore statico è quello di escludere esplicitamente i valori nulli:

IEnumerable<Foo> foos = GetFoos().Where(foo => foo != null); 

mi ritrovo a digitare .Where(x => x != null) molto, quindi ho avvolto in su in un metodo di estensione, e ora posso effettuare le seguenti operazioni:

IEnumerable<Foo> foos = GetFoos().NotNull(); 

Il problema è che Resharper non sa che NotNull() elimina i valori nulli. C'è un modo in cui posso insegnare Resharper su questo fatto? In generale, c'è un modo per dire a Resharper che un metodo IEnumerable -returning non avrà mai nulla in esso (in modo che io possa annotare direttamente GetFoos())?

So che posso usare per dire the NotNullAttribute ReSharper che la stessa enumerabile non è nullo, ma non riesco a trovare uno che parla delle contenuti del enumerabile.

Edit: Il metodo di estensione appare esattamente come ci si aspetterebbe:

[NotNull] 
public static IEnumerable<T> NotNull<T>(this IEnumerable<T> enumerable) 
{ 
    return enumerable.Where(x => x != null); 
} 
+0

Non uso il programma di ricerca. Ma se sa che 'foo! = Null' impedisce una' NullReferenceException', perché non sa che 'NotNull' salta anche null-foos? Puoi anche mostrare 'NotNull'? –

+1

@Tim hanno alcune regole incorporate nel plugin, quindi sa cosa '. Dove (...)' fa per esempio e il motore di analisi può agire di conseguenza. Ma non approfondisce i metodi dell'utente, perché risolvere questo nel caso generale equivarrebbe a risolvere il problema [fermare il problema] (http://en.wikipedia.org/wiki/Halting_problem). Purtroppo, non penso che ci sia un modo per annotare questa particolare regola ... '[ContractAnnotation (" ?? ")]' potrebbe essere stata una soluzione, ma non c'è neanche una sintassi per enumerabili. –

+0

@TimSchmelter Non lo so, ma sospetto che sia perché l'analizzatore non esegue un'ispezione approfondita del metodo per determinare dove è stato effettuato l'ultimo controllo del nullability. So che Resharper fa altri errori interessanti in quest'area - per esempio, se filtri i null con '.Where', e poi concatenando immediatamente un' .OrderBy', Resharper sembra perdere la consapevolezza che i valori nulli sono stati filtrati. – ean5533

risposta

3

È possibile utilizzare ItemNotNullAttribute che indica a ReSharper che nessun elemento di una raccolta può mai essere null.

+0

Eccellente! Sembra che hanno aggiunto che nel 2016 - così felice. – ean5533

1

Un modo come avete dichiarato è quello di utilizzare [NotNull] attributo che istruiscono il motore ReSharper per arrestare il controllo di errore di riferimento null per quella particolare variabile.

Oppure, se non si vuole utilizzare tale attributo è possibile opzionalmente utilizzare i commenti

// ReSharper disable PossibleNullReferenceException 
     var bars = foos.Select(foo => foo.Bar); 
// ReSharper restore PossibleNullReferenceException 

Per fare un punto a questa domanda, ReSharper non può attraversare attraverso runtime i valori di calcolo di istruzione in modo che possa fare un giudizio che non può essere nullo.

+0

L'attributo 'NotNull' verifica solo che * enumerable * non sia null, non verificherà che i * risultati * di enumerable non siano nulli. Inoltre, come indicato nei commenti sopra, non voglio disabilitare ripetutamente il controllo di riferimento nullo ogni volta che uso un enumerabile. – ean5533

Problemi correlati