2010-04-22 5 views
12

Qual è il modo migliore per fare questo in C#?C# - Proprietà Ricorsive/Riflessione Valori

string propPath = "ShippingInfo.Address.Street"; 

Avrò un percorso di proprietà come quello sopra letto da un file di mappatura. Devo essere in grado di chiedere all'Ordine dell'oggetto quale sarà il valore del codice sottostante.

this.ShippingInfo.Address.Street 

Bilanciamento delle prestazioni con eleganza. Tutte le relazioni grafiche degli oggetti dovrebbero essere uno a uno. Parte 2: quanto sarebbe difficile aggiungere la capacità di afferrare il primo se è un Elenco < o qualcosa del genere.

risposta

25

Forse qualcosa del genere?

string propPath = "ShippingInfo.Address.Street"; 

object propValue = this; 
foreach (string propName in propPath.Split('.')) 
{ 
    PropertyInfo propInfo = propValue.GetType().GetProperty(propName); 
    propValue = propInfo.GetValue(propValue, null); 
} 

Console.WriteLine("The value of " + propPath + " is: " + propValue); 

Oppure, se si preferisce LINQ, è possibile provare questo invece. (Anche se personalmente preferisco la versione non LINQ.)

string propPath = "ShippingInfo.Address.Street"; 

object propValue = propPath.Split('.').Aggregate(
    (object)this, 
    (value, name) => value.GetType().GetProperty(name).GetValue(value, null)); 

Console.WriteLine("The value of " + propPath + " is: " + propValue); 
+0

+1 perché l'esempio di codice è più breve della sua descrizione testuale * g * – Foxfire

+0

Mi piace. Sono corretto sulle difficoltà di esprimere questo.Ottima implementazione LINQ. – kmontgom

1

Suona come un insieme di invocazioni nidificati proprietà:

classe X ha una proprietà chiamata ShippingInfo; il tipo rappresentato da ShippingInfo ha un indirizzo di proprietà; il tipo rappresentato da Address ha una proprietà chiamata Street.

Quindi, supponendo che si conosce l'istanza appropriata di classe X di operare sia con: ("". ToCharArray())

  • tokenize la stringa tramite String.split ad uno string [], o qualcosa del genere così
  • inizio con il caso noto di X
  • uso riflessione avere la MethodInfo per il getter ShippingInfo
  • uso riflessione per ottenere il tipo restituito da ShippingInfo get()
  • invocare la getter utilizzando la riflessione
  • utilizzando il valore restituito dal ShippingInfo get() e il tipo di ritorno:
    • ottenere il MethodInfo per l'indirizzo getter del tipo restituito .....

e così via. Ottieni l'immagine.

Sembra un po 'lungo e noioso, e lo è. Ma è così che lo faresti tramite la riflessione.

Mi chiedo se è possibile fare la stessa cosa con LINQ agli oggetti?

La risposta alla parte 2 implica ottenere il valore iniziale di X dall'elenco <>.

+0

Riesci a riscriverlo? Non molto facile da capire - troppe parole :) – Nayan

+0

No. Se mai, è troppo breve e corto di dettagli. Questo è il problema con qualcosa come la riflessione, ci sono molti passaggi e ogni passo richiede conoscenze specifiche. Scusate. – kmontgom