2012-10-01 6 views
12

Ho un List<KeyValuePair<string, othertype>>. Devo fare qualcosa sulla falsariga diCome funziona List <T>.Fin funzionare quando T è una struttura?

list.Find(x=>x.Key=="foobar") 

Tuttavia, se questo non esiste nell'elenco, quale sarà il comportamento? Di solito restituisce null, ma le strutture non possono essere nulle.

+2

provare con 'int' e vediamo cosa succede. – Oded

+2

Il valore predefinito per tipo T, in particolare 'default (T)'. –

+0

Se si desidera che Trova restituisca null quando non viene trovata alcuna corrispondenza, considerare l'utilizzo di Tuple anziché KeyValuePair. – JamieSee

risposta

13

Restituirà lo default(T) che sarà lo stesso di new KeyValuePair<string, othertype>>(), ovvero una struttura inizializzata predefinita.

Fondamentalmente, il default per i tipi di riferimento è sempre null, e per tipi di valori (compresi struct) è il default (0 per numerici, false per bool, un struct con ogni campo insolvente per structures, etc.)

Così, per un default(KeyValuePair<string, othertype>>) si otterrebbe indietro un KVP dove il Key era null (predefinito per string) e qualunque sia la default(othertype) sarebbe (come negli esempi precedenti) ...

Dalla MSDN:

Il primo elemento che soddisfa le condizioni definite dal predicato specificato , se trovato; in caso contrario, il valore di default per il tipo T.

Usando questo, se si voleva controllare e vedere se è tornato il default, mi consiglia di controllare per yourResult.Key != null per vedere se hai un risultato, o si può utilizzare un diverso metodocome FindIndex come suggerisce Olivier.

+0

Potrebbe essere interessante notare che per il particolare tipo di valore 'Nullable ', perché l'inizializzazione di default risulta in' HasValue' come falso (come sarebbe qualsiasi Campo booleano di qualsiasi struttura), fa in modo che la struttura venga interpretata in molti contesti come un valore nullo. – supercat

14

Il mio consiglio è di usare FindIndex per i tipi non nullable

int index = list.FindIndex(x => x.Key == "foobar"); 
if (index >= 0) { 
    // found! 
    UseResult(list[index]); 
} 

Il valore predefinito default(T) viene restituito se Find() non ha esito positivo. Per i tipi non annullabili, questo risultato non può essere distinto dalle voci regolari con il valore predefinito. Questo vale anche per i tipi nullable quando l'elenco potrebbe contenere voci regolari null.

+1

+1: questa è la soluzione migliore. In questo caso, una coppia chiave-valore con una chiave nulla è improbabile che sia un valore legittimo, ma è possibile. Troppe persone lo dimenticano o, ad esempio, un 'Elenco ' può contenere valori nulli. – phoog

+1

+1: molto bello. Non volevo confrontarmi con un default; come hai detto tu, nella maggior parte dei casi, non c'è modo di determinare la differenza. –

3

La struttura è un tipo di valore. quindi, In caso di struttura Trova restituirà il valore predefinito della struttura.

ESEMPIO:

consente di dire che abbiamo struttura come di seguito,

public struct Test 
{ 
    public int i; 
} 

List<Test> list = new List<test>() { new Test { i = 1 } }; 
Test result = list.Find(o => o.i == 2); 

In precedenza valore del risultato Find come nuovo Test(). puoi confrontare il valore in base al codice sottostante.

if (resul.Equals(new Test())) 
{ 

     //Do something 
} 
else 
{ 
        //Do something  
} 

O

if (resul.Equals(default(Test))) 
{ 

     //Do something 
} 
else 
{ 
        //Do something  
} 
+0

Eh, che se la condizione sembra così ... sbagliata. Quello non funzionerebbe mai per i tipi di riferimento :) le strutture non sono sicuramente qualcosa che uso tutti i giorni anche se – Earlz

+0

ho cambiato '==' in Equals. –

+0

Sconsigliamo di fare un '== nuovo Test()', è un po 'pesante dato che '==' su 'struct' è riflettente. Preferirei invece controllare il campo 'Key' per' null' nell'esempio 'OP'. –

Problemi correlati