2014-10-07 34 views
37

C'è un modo per ottenere il valore della chiave data nella seguente eccezione in C# in un modo che interessa tutte le classi generiche? Penso che questo sia un grosso errore nella descrizione delle eccezioni di Microsoft.La chiave data non era presente nel dizionario. Quale chiave?

"The given key was not present in the dictionary." 

Un modo migliore sarebbe:

"The given key '" + key.ToString() + "' was not present in the dictionary." 

Solutions potrebbe coinvolgere mixins o classi derivate forse.

+11

Questa domanda sembra essere off-topic perché è una farsa sull'implementazione di un messaggio di eccezione e non una domanda di programmazione. – Servy

+1

Ovviamente, è possibile utilizzare il debugger per trovare esattamente il contesto, quindi trovare la chiave. – Mephy

+6

Il problema è che il debugger non è sempre disponibile, ad esempio durante la lettura del file di registro. – Andreas

risposta

10

Nel caso generale, la risposta è no

Tuttavia, è possibile impostare il debugger di rompere nel punto in cui l'eccezione viene lanciata prima. A quel tempo, la chiave che non era presente sarà accessibile come valore nello stack di chiamate.

In Visual Studio, questa opzione si trova qui:

debug → Eccezioni ... → Eccezioni Common Language Runtime → System.Collections.Generic

lì, è possibile selezionare la casella Gettato.


Per le istanze più specifici in cui è necessario le informazioni in fase di esecuzione, purché il codice utilizza IDictionary<TKey, TValue> e non legato direttamente a Dictionary<TKey, TValue>, è possibile implementare la propria classe dizionario che fornisce questo comportamento.

+0

Questo di solito come eseguo il debugger – AaronLS

+0

Ciao @Sam, a quel punto nello stack di chiamate trovi questo valore? – user919426

+0

VS 2017 (v15.5.7) è come: Debug -> Windows -> Impostazioni eccezione -> quindi selezionare System.Collections.Generic.KeyNotFoundException –

4

Se si desidera gestire miss chiave che si dovrebbe usare TryGetValue

https://msdn.microsoft.com/en-gb/library/bb347013(v=vs.110).aspx

string value = ""; 
if (openWith.TryGetValue("tif", out value)) 
{ 
    Console.WriteLine("For key = \"tif\", value = {0}.", value); 
} 
else 
{ 
    Console.WriteLine("Key = \"tif\" is not found."); 
} 
+0

Ciò presuppone che l'utilizzo previsto per la chiave non sia presente. potrebbe non essere il caso: può essere legittimamente un caso eccezionale – Servy

+0

grazie mille –

37

Questa eccezione viene generata quando si tenta di indicizzare a qualcosa che non c'è, per esempio:

Dictionary<String, String> test = new Dictionary<String,String>(); 
test.Add("Key1,"Value1"); 
string error = test["Key2"]; 

Spesso, qualcosa come un oggetto sarà la chiave, che indubbiamente rende più difficile da ottenere. Tuttavia, si può sempre scrivere le seguenti (o addirittura avvolgetelo in un metodo di estensione):

if (test.ContainsKey(myKey)) 
    return test[myKey]; 
else 
    throw new Exception(String.Format("Key {0} was not found", myKey)); 

o più efficiente (grazie a @ScottChamberlain)

T retValue; 
if (test.TryGetValue(myKey, out retValue)) 
    return retValue; 
else 
    throw new Exception(String.Format("Key {0} was not found", myKey)); 

Microsoft ha scelto di fare questo, probabilmente perché sarebbe inutile se usato sulla maggior parte degli oggetti. È abbastanza semplice da fare da solo, quindi tira il tuo!

+11

facendo 'ContainsKey', quindi l'indicizzatore causerà due ricerche nel dizionario. Fare un 'TryGetValue' sarebbe solo una ricerca e puoi semplicemente usare l'output booleano di quello per scegliere il tuo blocco if/else. –

+1

@ScottChamberlain Molto vero. Aggiunto come implementazione aggiuntiva. – BradleyDotNET

+0

prova test.keys.contains (chiave) che restituisce un valore booleano. – Kurkula

Problemi correlati