hshen
hshen

Reputation: 476

linq select clause syntax

Linq Select method takes Func as input parameter. This means I can have multiple statements in selector for Select, such as

var myresult = sources.Select(s => 
     {int x; if (s.val = high) {x=1} else if (s.val = med) {x=2} else {x=3}; return x;
     }
  )

How can I do this using Linq query syntax

var myresult = from s in sources
       select ...

Here, the code in Func part (if ... else if .. else) is artificial. What I really want to know is the syntax of select clause, which may be described as

select select-expression

What is the syntax of

select-expression

Upvotes: 2

Views: 2386

Answers (4)

hshen
hshen

Reputation: 476

MSDN indicates select is a contextual keyword of C# 4.0. So I checked the C# Language Specififcation 4.0. Its Select clauses section (7.16.2.5) specifies that

A query expression of the form
from x in e select v
is translated into
( e ) . Select ( x => v )
except when v is the identifier x, the translation is simply
( e )

As the result, the syntax for

select select-expresion

select-expression should be anything that can be used as TResult in Select Method. So the functionality can be done using anonymous Func in Select method may not be able to achieved using select clause.

Conclusion is that you should stick with Method syntax as this is how the code really runs behind the scene.

Upvotes: 0

SLaks
SLaks

Reputation: 887415

This is not possible.

If you really want to, you could create an Func<T> from an anonymous method and invoke it, but that would be horrible.

Upvotes: 0

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59111

Instead of special-casing values, with the if/else equivalent of a switch statement, it is more Linq-friendly to group and filter your values:

var myResult = from s in sources
               group by s.val into g
               select new { Val = g.Key, Sources = g };

var groupHigh = myResult.Where(i => i.Val == high);
var groupMedium = myResult.Where(i => i.Val == medium);
var groupOther = myResult.Except(groupHigh.Concat(groupMedium));

Note that the code I've provided is just a starting place, and isn't the best way to achieve your specific goal. I'd address this in one of these ways:

  • Change how group by is used (use SomeFunction(s.Val) instead of directly using s.Val)
  • Change the code around this query to flow better with the natural groupings, so I didn't require the groups to be transformed

Upvotes: 0

Anthony Pegram
Anthony Pegram

Reputation: 126834

I wouldn't want to see your first version in my code. If you need to have what is basically a full function in the lambda, I would rather see the lambda simply invoke a full function! In other words...

theQuery.Select(s => GetX(s)); // just define a GetX function

And that would also be a straightforward translation to query expression syntax

from s in sources
select GetX(s);

You would not be able to put your full code block into the query expression syntax. You could translate your given logic to something usable (yet messy), however I'm quite sure your snippet is just a general example. On the offhand change it isn't, you might try

select s.val == high ? 1 : (s.val == med ? 2 : 3); // totally messy

Upvotes: 2

Related Questions