10

Let's say I have a class like:

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

Now, let's assume I have a public List<Foo> myList which I want to filter by Linq as so:

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

Everything is nice and clear until now.

But how can access the property by variable? Something like:

string myProperty = "Title";

var x = myList.Where(f => f.myProperty == myValue);
Surjit Samra
  • 4,614
  • 1
  • 26
  • 36
Rafael Herscovici
  • 16,558
  • 19
  • 65
  • 93

5 Answers5

22

You can write an extension method

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);
    }
}

and use it like this

var x = myList.Where(f => f.GetProperty("Title") == myValue);
L.B
  • 114,136
  • 19
  • 178
  • 224
4

This is not the type of situation that LINQ is used for. LINQ is a fluent interface for manipulating collections. Accessing members via a textual representation is done with reflection.

object GetProperty(Foo f, string propertyName) {
  var type = typeof(Foo);
  var propInfo = type.GetProperty(propertyName);
  return propInfo.GetValue(f, null);
}
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
2

I know this is an old thread but here is another way to do it. This has the advantage of being significantly faster if you need to do it in a loop. I have converted the result out of "func" to be object to make it a bit more general purpose.

        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);

In the original question the code was being used inside linq so speed could be good. It would be possible to use "func" direct in the where clause also if it was built correctly, eg

        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();
MikeKulls
  • 2,979
  • 2
  • 25
  • 30
2

If you need to compose your queries dynamically on the fly, you can use the LINQ Dynamic Query library, a sample from Microsoft:

This sample shows a technique for composing LINQ statements on the fly, dynamically, at run time.

Reference the library in your code:

using System.Linq.Dynamic;

Your query would look like this:

// 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);

It's also possible to use placeholder in the query string, which improves readability (somewhat):

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

See also this post from Scott Guthrie: Dynamic LINQ Part 1: Using the LINQ Dynamic Query Library (I don't think there ever was a part 2...)

Note: you have to compile the sample code from Microsoft and reference the built assembly, or you could include the code in your own project.

Michiel van Oosterhout
  • 22,839
  • 15
  • 90
  • 132
  • hmm, any reason why it is not part of standard .net framework , looks tempting .. – Surjit Samra Jan 07 '12 at 16:17
  • @SurjitSamra At the time of the first LINQ release (Visual Studio 2008, C# 3.0), Microsoft wrote a lot of samples to help everyone understand the power of LINQ. This was just one of those samples, which by itself can be very helpful but may just be too limited to be part of the framework. – Michiel van Oosterhout Jan 07 '12 at 16:54
  • If I will be in this situation then frankly I will prefer LB's answer – Surjit Samra Jan 07 '12 at 20:35
0

you cant use linq dynamic query from microsoft here is sample code

 var query =  db.Customers.Where("City == @0 and Orders.Count >= @1", "London", 10).
            OrderBy("CompanyName").
            Select("New(CompanyName as Name, Phone)"); 
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574