Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing a regular method with an anonymous method in C#/LINQ

I have a LINQ query that looks like this:

public IEnumerable<Foo> SelectFooBars()
{
    return
        from
            f in foos
        join
            b in bars
            on f.BarId equals b.Id
        select
            AddMissingProp(f, b.MissingProp);
}

public void AddMissingProp(Foo foo, string missingProp) // substitute this with inline lambda
{
    foo.MissingProp = missingProp;
    return foo;
}

I would like to get rid of AddMissingProp and use some form of a lambda in my select clause instead.

I attempted...

...
select
    (f, b) => { f.MissingProp = b.MissingProp; return f }

...but I got the following error:

A local variable named 'f' cannot be declared in this scope because it would give a different meaning to 'f', which is already used in a 'parent or current' scope to denote something else.

How can I "lambda-ize" my query?


Update

This also doesn't work:

...
select
    () => { f.MissingProp = b.MissingProp; return f }

I get the following error:

The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.

I didn't change the join clause at all, so I'm perplexed.

like image 980
devuxer Avatar asked Jan 07 '10 19:01

devuxer


1 Answers

I think icambron is right, IMHO the better readable version is this:

  var fooBar = from 
                 f in foos
               join 
                 b in bars
                 on f.BarId equals b.Id 
               select new {f,b};

   foreach(var x in fooBar)
        x.f.MissingProp = x.b.MissingProp;

   // EDIT due to comments: add this if you 
   // need IEnumerable<Foo> returned
   return fooBar.Select(fb => fb.f);

The from join select statements are for queries, they should not be misused for mutating the contents of a sequence.

EDIT: Here is another link providing some insights why using a functional form of ForEach is not a good idea.

like image 152
Doc Brown Avatar answered Oct 13 '22 12:10

Doc Brown