tags:

views:

79

answers:

3

Can anyone tell me how to best possible way to convert the following code to LINQ:

static int MyMethod(MyClass my, bool b)
{
  int cnt = 0;

  foreach(SomeClass cls in my.SomeMethod()
  {
    cnt = cnt + cls.length;
  }

  if(b == true)
  {
    foreach(MyClass aa in my.SomeOtherMethod())
    {
      cnt = cnt + MyMethod(aa, true); // recursive
    }
  }

  return cnt;
}

Please see that I know that the code above works fine, but I need to write it in LINQ and compare.

+1  A: 

You cannot write recursive queries with LINQ.

Darin Dimitrov
Oh, you *can* - they're just excruciating: http://blogs.msdn.com/b/madst/archive/2007/05/11/recursive-lambda-expressions.aspx
Marc Gravell
@Marc, great link.
Darin Dimitrov
+2  A: 

As Darin says, you can't easily recurse without doing so explicitly - but you can still simplify this code with LINQ:

static int MyMethod(MyClass my, bool b)
{
  int cnt = my.SomeMethod().Sum(cls => cls.length);    
  if (b)
  {
      cnt += my.SomeOtherMethod().Sum(aa => MyMethod(aa, true));
  }    
  return cnt;
}
Jon Skeet
thank you jon for solution
Jamie
+1  A: 

First of all, you should use the solution by Jon, because it is the most straightforward and readable soltion you can get. However, you can write recursive Func<...> declarations in C#, so the code could be rewritten like this:

Func<MyClass, bool, int> myFoo = null;
f = (my, b) =>
    my.SomeMethod().Sum(cls => cls.length) +
    (b ? my.SomeOhterMethod().Sum(aa => myFoo(aa, true)) : 0);

This is essentially the same thing as what Jon posted, with the exception that I'm using Func<..> instead of a full method. (This can be useful for encoding recursion in LINQ queries, but I think it is useful only very rarely)

Tomas Petricek
You need to give `myFoo` a value to start with - typically `null` - so that it's definitely assigned before the second statement. I think you meant to assign to `myFoo`, too :) Obviously the F# version would be somewhat neater...
Jon Skeet
@Jon: Yes, I wanted to initialize it with `null` (because the C# compiler uses the _current_ value, it will not use `null` during the recursive call). The F# version would be a bit simpler because F# syntax for "functions" is more lightweight, but it is essentially the same (unless you use tricks like `Y` combinator, but that's not very practical).
Tomas Petricek