2012-01-07 12 views
5

Diciamo che ho una classe come:Linq proprietà l'accesso da parte variabile

public class Foo 
{ 
    public string Title {get;set;} 
} 

Ora, supponiamo Ho un public List<Foo> myList cui voglio filtrare per Linq come così:

var x = myList.Where(f => f.Title == myValue); 

Tutto è bello e chiaro fino ad ora.

Ma come si può accedere alla proprietà tramite variabile? Qualcosa di simile:

string myProperty = "Title"; 

var x = myList.Where(f => f.myProperty == myValue); 

risposta

12

È possibile scrivere un metodo di estensione

public static class MyExtensions 
{ 
    public static object GetProperty<T>(this T obj, string name) where T : class 
    { 
     Type t = typeof(T); 
     return t.GetProperty(name).GetValue(obj, null); 
    } 
} 

e utilizzarlo come questo

var x = myList.Where(f => f.GetProperty("Title") == myValue); 
+0

Mi è piaciuto molto! Grazie. – Dementic

3

Questo non è il tipo di situazione per cui LINQ è utilizzato. LINQ è un'interfaccia fluente per manipolare le raccolte. L'accesso ai membri tramite una rappresentazione testuale avviene con la riflessione.

object GetProperty(Foo f, string propertyName) { 
    var type = typeof(Foo); 
    var propInfo = type.GetProperty(propertyName); 
    return propInfo.GetValue(f, null); 
} 
0

si utilizza gergo LINQ dynamic query from microsoft qui è il codice di esempio

var query = db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10). 
      OrderBy("CompanyName"). 
      Select("New(CompanyName as Name, Phone)"); 
+0

Perché è stato collegato a un accordo di licenza? –

+1

lol, è necessario accettare per scaricare il codice di esempio. – Dementic

1

Se è necessario comporre le vostre domande in modo dinamico al volo, è possibile utilizzare la libreria LINQ Dynamic Query, un campione da Microsoft:

Questo esempio mostra una tecnica per la composizione delle istruzioni LINQ sul volo , in modo dinamico, in fase di esecuzione.

riferimento la libreria nel codice:

using System.Linq.Dynamic; 

Vostri criteri sarebbe simile a questa:

// You can use a string as the argument for the Where method 
// meaning you can compose this string dynamically 
string myProperty = "Title"; 
var x = myList.Where(myProperty + " = " + myValue); 

E 'anche possibile utilizzare segnaposto nella stringa di query, che migliora la leggibilità (un po'):

var x = myList.Where("@0 = @1", myProperty, myValue); 

Vedere a LSO questo post da Scott Guthrie: Dinamica LINQ Parte 1: Using the LINQ Dynamic Query Library (non credo che ci sia mai stata una parte 2 ...)

Nota: è necessario compilare il codice di esempio di Microsoft e fare riferimento al assemblea costruita, o potresti includere il codice nel tuo progetto.

+0

hmm, qualsiasi motivo per cui non fa parte del framework .net standard, sembra allettante .. –

+0

@SurjitSamra Al momento della prima versione di LINQ (Visual Studio 2008, C# 3.0), Microsoft ha scritto molti esempi per aiutare tutti a capire il potere di LINQ. Questo era solo uno di quei campioni, che di per sé può essere molto utile, ma potrebbe essere troppo limitato per far parte del framework. –

+0

Se sarò in questa situazione, francamente preferirò la risposta di LB –

1

So che questo è un vecchio thread, ma qui è un altro modo per farlo. Questo ha il vantaggio di essere molto più veloce se è necessario farlo in un ciclo. Ho convertito il risultato di "func" in oggetto per renderlo un po 'più generico.

 var p = Expression.Parameter(typeof(string)); 
     var prop = Expression.Property(p, "Length"); 
     var con = Expression.Convert(prop, typeof(object)); 
     var exp = Expression.Lambda(con, p); 
     var func = (Func<string, object>)exp.Compile(); 

     var obj = "ABC"; 
     int len = (int)func(obj); 

Nella domanda originale il codice veniva utilizzato all'interno di linq quindi la velocità poteva essere buona.Sarebbe possibile utilizzare "func" direttamente nella clausola where anche se è stato compilato correttamente, ad esempio

 class ABC 
     { 
      public string Name { get; set; } 
     } 

     var p = Expression.Parameter(typeof(ABC)); 
     var prop = Expression.Property(p, "Name"); 
     var body = Expression.Equal(prop, Expression.Constant("Bob")); 
     var exp = Expression.Lambda(body, p); 
     var func = (Func<ABC, bool>)exp.Compile(); 

     ABC[] items = "Fred,Bob,Mary,Jane,Bob".Split(',').Select(s => new ABC() { Name = s }).ToArray(); 
     ABC[] bobs = items.Where(func).ToArray(); 
Problemi correlati