-2

I found myself in a situation where I had to do some stuff with elements of a list and then remove them from that list :

foreach (var element in someList.Where(e => e.IsMatching))
{
    // do some stuff
}

someList.RemoveAll(e => e.IsMatching);

This woks perfectly but I don't like the duplicate lambda, so I declared a Func<T, bool> x = e => e.IsMatching; and then tried to use x as a parameter for .Where and .RemoveAll but I wasn't able to use x for .RemoveAll because its overload only accepts Predicate<T>.

Why isn't an implicit nor explicit cast possible since both have the same return and parameter types?

(I am not looking for a way to make the conversion, everything about it is already in this quesion)

nalka
  • 1,894
  • 11
  • 26
  • 4
    Why don't use the solution from linked thread? – Pavel Anikhouski Jan 20 '20 at 15:22
  • 2
    ... because the language doesn't allow implicit or explicit conversions between different delegate types (even if they have compatible signatures) – canton7 Jan 20 '20 at 15:24
  • @PavelAnikhouski as mentionned in the question, i'm not looking for a way to perform the conversion, i'm just asking why is the cast not possible – nalka Jan 20 '20 at 15:25
  • @canton7 Ok I kind of guessed that but why didn't the C# designers implement this? – nalka Jan 20 '20 at 15:28
  • 1
    Because there was no need? Remember that `Func` is a relatively new addition: the original intention, as far as I can gather, was that each *use* of a delegate would get its own delegate type: the name of the delegate and the names of its parameters were just as important as the *types* of the parameters. Under that, why would you be able to implicitly cast a `Predicate` (which is used for determining if an object meets a criterion) to, say, a `Converter` (which is used for mapping between data types): they're different things entirely! Then linq came along... – canton7 Jan 20 '20 at 15:31
  • 3
    If you would have two classes like `class A { int a; }` and `class B { int a; }` you would also not come up with the idea of assignability among these types. – Holger Jan 20 '20 at 15:38
  • Yeah I understand the problem now, while it could look interesting to have in some cases, it could also lead to unconsistent behaviours which is definitely not acceptable – nalka Jan 20 '20 at 15:41

1 Answers1

1

It is a little silly that the IEnumerable<T>.Where extension method and List<T>'s RemoveAll method take two different types. However, this is a simple work-around, since the local function can be used to initialize both a Func<int, bool> and a Predicate<int>:

var l = new List<int> {1, 2, 3, 5, 5, 6, 6};
bool Pred(int i) => i < 5;
var wh = l.Where(Pred);
var rem = l.RemoveAll(Pred);
Flydog57
  • 6,851
  • 2
  • 17
  • 18