3

How can I define a lambdaexpression that I want to use in a linq query as a variable?

For example when sorting a generic list by different properties of the listitems:

 IList<SampleClass> list = new List<SampleClass>();

 // Populate list
 ...

 list.OrderBy(sampleclass => sampleclass.property1);
 list.OrderBy(sampleclass => sampleclass.property2);

I would like to define the lambda expression (sampleclass => sampleclass.property1) in a variable and call:

// ??? define expression in a variable ???
Expression expression = sampleclass => sampleclass.property1;

// Sort list by variable expression
list.OrderBy(expression);

Thanks in advance Tobi

6 Answers 6

5

You can use one of Func overloads (Func<T, TResult> precisely):

Func<SampleClass, PropertyType> expr = sampleclass => sampleclass.property1;
list.OrderBy(expr);

PropertyType is the type of variable stored as property1 in your SampleClass. If it was for example string, you would use Func<SampleClass, string>.

Sign up to request clarification or add additional context in comments.

Comments

2

Define a Func<TSampleClass, TPropertyType> as follows:

  List<SampleClass> list = new List<SampleClass>();   
  Func<SampleClass, int> expr = (c) => c.SomeProperty;
  _HungerLevel = level;


  class SampleClass
  {
    public int SomeProperty { get; set; }
  }

2 Comments

this does not work: "Cannot assign lambda-expression to an implicity-typed local variable"
@Tobias Did you use the var keyword when declaring the Func?
1

You can use:

Func<SampleClass, int> f = sampleClass => sampleClass.Property1;
list.OrderBy(f);

This presumes the type of Property1 is int.

Comments

1

You have almost already done it.

The parameter is any function taking an item from the sequence and giving its key as a result (the key on which the ordering will be done). A lambda expression is just a variety of such a function.

These notations are possible :

list.OrderBy(sampleclass => sampleclass.property1);

or

Func<SampleClass,string> getKey = sampleclass => sampleclass.property1;
list.OrderBy(getKey);

or

string GetKey(SampleClass sampleclass)
{
    return sampleclass.property1;
}

list.OrderBy(GetKey);

(I supposed here that property1 was a string but it's of course not a requirement !)

Comments

0

Just like other people said, you can use Func<T, TResult> to store delegate to your function.

If you want to use something else than Linq-To-Objects, then you should enclose this in Expression too. Something like Expression<Func<T, TResult>>.

Comments

0

If you are talking purely about LINQ to Objects, there's no need for Expressions here because the argument to Enumerable.OrderBy is a Func delegate:

var list = new List<SampleClass> ();

Func<SampleClass, PropertyType1) orderSelector1 = (obj => obj.Property1); // parentheses for clarity
var sequence1 = list.OrderBy (orderSelector1);

Func<SampleClass, PropertyType2) orderSelector1 = (obj => obj.Property2);
var sequence2 = list.OrderBy (orderSelector2);

If you want to assign multiple times, you can make Func return object:

var list = new List<SampleClass> ();
Func<SampleClass, object> orderSelector;

orderSelector = (obj => obj.Property1);
var sequence1 = list.OrderBy (orderSelector);

orderSelector = (obj => obj.Property2);
var sequence2 = list.OrderBy (orderSelector);

If you truly want dynamic property selection, i.e. calling OrderBy with a property specified by a string, you would need Expressions. There are plenty of examples in this thread that allow you to do something like:

var list = new List<SampleClass> ();
var sequence1 = list.OrderBy ("Property1");
var sequence2 = list.OrderBy ("Property2");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.