views:

1093

answers:

3

Yes I've seen this but I couldn't find the answer to my specific question.

Given a lambda testLambda that takes T and returns a boolean (I can make it either Predicate or Func that's up to me)

I need to be able to use both List.FindIndex(testLambda) (takes a Predicate) and List.Where(testLambda) (takes a Func).

Any ideas how to do both?

+2  A: 

I got this:

Func<object, bool> testLambda = x=>true;
int idx = myList.FindIndex(x => testLambda(x));

Works, but ick.

George Mauer
+8  A: 

Easy:

Func<string,bool> func = x => x.Length > 5;
Predicate<string> predicate = new Predicate<string>(func);

Basically you can create a new delegate instance with any compatible existing instance. This also supports variance (co- and contra-):

Action<object> actOnObject = x => Console.WriteLine(x);
Action<string> actOnString = new Action<string>(actOnObject);

Func<string> returnsString = () => "hi";
Func<object> returnsObject = new Func<object>(returnsString);

If you want to make it generic:

static Predicate<T> ConvertToPredicate<T>(Func<T, bool> func)
{
    return new Predicate<T>(func);
}
Jon Skeet
These sort of games make me angry. I guess I get why they did it but still...
George Mauer
They could at least have provided an overload for FindIndex
George Mauer
What sort of "games"? What do you mean?
Jon Skeet
Predicate<T> conceptually == Func<T, bool> but they're still not the same. Yes, Predicate<T> was a .Net 2.0 thing but now that its deprecated there should be one way to do the same thing.
George Mauer
@George: There would be one way to do things if they could retire Predicate<T>. Unfortunately, some code was written using it, and retiring this type would break that code.
David B
Exactly. Backward compatibility is a *big* issue.
Jon Skeet
Sure, but they could provide some overloads for methods that use Predicate<T> or even better, add an implicit type conversion.
George Mauer
@George: that'd be a lot of overloads everything obsoleted... as for implicit type conversions, have you looked at what that does to the complexity and usability of C++ (e.g. that bool and void* can be confused in resolving overloads)?
Pontus Gagge
It would also break the use of lambda expressions for those methods, because they'd be equally valid for the two overloads.
Jon Skeet
A: 

Sound like a case for

static class ListExtensions
{
  public static int FindIndex<T>(this List<T> list, Func<T, bool> f) {
    return list.FindIndex(x => f(x));
  }
}

// ...
Func<string, bool> f = x=>Something(x);
MyList.FindIndex(f);
// ...

I love C#3 ...

MartinStettner