Domanda

mi piacerebbe implementare un metodo che mi permette di accedere a una proprietà di un / oggetto anonimo sconosciuto (-graph) in maniera tardiva / dinamico (io non so nemmeno come chiamare correttamente).

Ecco un esempio di quello che mi piacerebbe realizzare:

// setup an anonymous object
var a = new { B = new { C = new { I = 33 } } };

// now get the value of a.B.C.I in a late-bound way
var i = Get(a, "B.C.I"); 

Ed ecco una semplice implementazione utilizzando la riflessione "classico":

public static object Get(object obj, string expression)
{
    foreach (var name in expression.Split('.'))
    {
        var property = obj.GetType().GetProperty(name);
        obj = property.GetValue(obj, null);
    }
    return obj;
}

Quali altre opzioni ho con C # / .NET 4 per implementare qualcosa di simile, come mostrato sopra, ma forse più semplice, più performante, ecc.?

Forse ci sono modi per raggiungere la stessa cosa, che mi permettesse di specificare expression utilizzando un'espressione lambda invece di una stringa? alberi di espressione sarebbe disponibile in qualsiasi modo (ad esempio, come mostrato in questa domanda ) ?

Aggiorna : l'oggetto e l'espressione sono passati nel mio codice tramite una chiamata di servizio web. Ecco perché ho usato object e string nel mio metodo Get().

È stato utile?

Soluzione

Hai effettivamente solo hanno l'espressione come una stringa? E 'noto al momento della compilazione, basta che i tipi stessi non sono noti (o sono difficili da esprimere)? Se è così:

dynamic d = a;
int i = d.B.C.I;

Se davvero avete solo come una stringa (ad esempio, come inserito dall'utente di dati) che rende la vita molto più difficile, e nessuno dei C # 4 caratteristiche davvero aiutare. Si potrebbe potenzialmente valutarla come uno script IronPython o qualcosa del genere ...

EDIT: Okay, dopo l'aggiornamento sembra che tu sei in quest'ultima situazione - in questo caso, non so di un modo migliore rispetto all'utilizzo di riflessione. Alcune delle proprietà incorporata legame costruito per interfacce utente può aiutare, ma non so di un modo pulito di accedervi.

Altri suggerimenti

Se si desidera utilizzare # stile C, è possibile utilizzare il compilatore Mono come un servizio dall'applicazione. Descrivo come farlo qui: Mono Compiler as a Service (MCS)

Come approccio alternativo, si potrebbe utilizzare la riflessione per mettere tutte le proprietà del vostro oggetto in un ExpandoObject quindi utilizzarlo come un dizionario (perché ExpandoObject implementa IDictionary). In alternativa, è possibile utilizzare JSON.NET e call JObject.FromObject, che si trasformerà un oggetto normale in un jobject che è accessibile in un dizionario-come stile (e come un ulteriore vantaggio ha il supporto grafico ricorsiva). Infine, è possibile utilizzare lo stesso approccio per scaricare il vostro oggetto in un dizionario di dizionari.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top