2010-04-28 15 views
9

Attualmente sto cercando di scrivere un metodo Dump() da LinqPad equivalente a Iin C# per il mio personale divertimento. Sto passando da Java a C# e questo è un esercizio piuttosto che un requisito aziendale. Ho quasi tutto funzionante tranne che per il dump di un dizionario.Rif. C# - Come posso sapere se l'oggetto o è di tipo KeyValuePair e quindi lanciato?

Il problema è che KeyValuePair è un tipo di valore. Per la maggior parte degli altri tipi di valore, chiamo semplicemente il metodo ToString, ma questo è insufficiente in quanto KeyValuePair può contenere Enumerables e altri oggetti con metodi ToString indesiderati. Quindi ho bisogno di allenarmi se si tratta di KeyValuePair e poi di lanciarlo. In Java potrei usare generici jolly per questo, ma non conosco l'equivalente in C#.

La tua ricerca, dato un oggetto o, determina se è un KeyValuePair e chiama Stampa sulla sua chiave e valore.

Print(object o) { 
    ... 
} 

Grazie!

risposta

31

Se non si conosce il tipo memorizzati nel KeyValuePair è necessario esercitare un po 'di codice di riflessione.

Diamo un'occhiata a ciò che è necessario:

prima cosa, assicurarsi che il valore non è null:

if (value != null) 
{ 

Poi, Assicuriamo il valore è generico:

Type valueType = value.GetType(); 
    if (valueType.IsGenericType) 
    { 

Poi , estrai la definizione di tipo generico, che è KeyValuePair<,>:

 Type baseType = valueType.GetGenericTypeDefinition(); 
     if (baseType == typeof(KeyValuePair<,>)) 
     { 

quindi estrarre i tipi di valori in essa:

  Type[] argTypes = baseType.GetGenericArguments(); 

codice finale:

if (value != null) 
{ 
    Type valueType = value.GetType(); 
    if (valueType.IsGenericType) 
    { 
     Type baseType = valueType.GetGenericTypeDefinition(); 
     if (baseType == typeof(KeyValuePair<,>)) 
     { 
      Type[] argTypes = baseType.GetGenericArguments(); 
      // now process the values 
     } 
    } 
} 

Se hai scoperto che l'oggetto contenga in effetti una KeyValuePair<TKey,TValue> si può estrarre la chiave attuale e un valore simile al seguente:

object kvpKey = valueType.GetProperty("Key").GetValue(value, null); 
object kvpValue = valueType.GetProperty("Value").GetValue(value, null); 
+0

Stavo proprio per suggerire esattamente quello .. :) Buona risposta – Tigraine

+0

Sorprendente risposta, grazie mille – Logan

+2

l'uso della riflessione qui influirà molto sulle prestazioni? – JDandChips

0
+0

Il collegamento in lingua inglese è http://msdn.microsoft.com/library/scekt9xw(VS.80).aspx –

+1

Penso che questo si complichi con i generici. Dal momento che KeyValuePair non è lo stesso di KeyValuePair .. E in realtà a lui non importa di che tipo è, purché ci sia un .ToString() in esso .. (T: class) – Tigraine

1

Presunto si sta utilizzando il KeyValuePair generico quindi è necessario probabilmente vuole testare per un particolare istanziazione, ad esempio, creato utilizzando una stringa sia per chiave e il valore:

public void Print(object o) 
{ 
    if (o == null) 
     return; 

    if (o is KeyValuePair<string, string>) 
    { 
     KeyValuePair<string, string> pair = (KeyValuePair<string, string>)o; 
     Console.WriteLine("{0} = {1}", pair.Key, pair.Value); 
    } 
} 

Se si desidera verificare per qualsiasi tipo di KeyValuePair allora avrete bisogno di utilizzare la riflessione. Fai?

Problemi correlati