Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method with no parameters in c# and still a method?

All i am trying to do is to check whether all elements of list B are in list A

        if (listA.All(element => listB.Contains(element))
        {
            return;
        }

Someone came up with another solution saying this would work and it worked!

       if (listA.All(listB.Contains))
            return;

Now, (I know it works),

  1. Why did the compiler doesn't require a () near contains in the second method?
  2. If in future, say, I want this to compare case-insensitive, how would I do it with second method ?

Thanks in advance.

like image 525
now he who must not be named. Avatar asked Dec 12 '22 13:12

now he who must not be named.


1 Answers

The All method asks for a predicate as a parameter: Func<T, bool> where T is the same type is the items in the List<T>. This code works because it provides just such a method. The All method will return a value indicating whether the result of calling the provided predicate on each item in the list results in true. The parameter is a reference to the Contains method which matches the required Func<T, bool>, taking a single parameter T and returning a bool.

Consider these two lines of code:

Func<string, bool> predicate1 = s => s.Length > 5;
Func<string, bool> predicate2 = listB.Contains;

Both of these lines work because the expressions to the right of the assignment operators evaluate to methods that take a single string parameter, and return a bool. You could pass predicate1 or predicate2 into the All method. It's the same as the code you provided, except that the predicate is passed directly, instead of being stored in a variable first and the variable passed in.

The Contains method is not actually called as the parameter though. It is only called internally by the All method.

If you wanted to do a case-insensitive search, and use the same sort of syntax as above, you would need a method that performed a case-insensitive search. You could always just use a custom anonymous method though:

listA.All(x => listB.Any(
    z => string.Equals(x, z, StringComparison.OrdinalIgnoreCase)));
like image 151
Dan Avatar answered Dec 15 '22 00:12

Dan