Saeid
Saeid

Reputation: 693

How apply a method to all list members using very short linq with lambda omitted?

Say I have a List and I want to check if the members are all equal to "some string":

myList.All(v => v.Equals("some string"))

I think this would do the same (or would it?!):

myList.All("some string".Equals)

but what if instead of .Equals I want to use my own method?

public bool LessThan16Char(string input)
{
    return (input.Length < 16);
}

How do I replace .Equals with LessThan16Char?


What if the method has a second parameter (e.g. lessthan(string Input, Int lessThanVal))

I would also appreciate any article on the web that describes these sort of things, Thanks.

Upvotes: 2

Views: 84

Answers (3)

Hamid Pourjam
Hamid Pourjam

Reputation: 20764

As I commented before you can use myList.All(LessThan16Char).

Keep in mind that myList.All(LessThan16Char) is different from myList.All(x => LessThan16Char(x)).

The second one creates an extra indirection. Compiler translates x => LessThan16Char(x) to a method which gets an string as an input and call LessThan16Char for it.

You can see the different IL generated.

1 . myList.All(LessThan16Char)

IL_0008:  ldarg.0     
IL_0009:  ldftn       UserQuery.LessThan16Char
IL_000F:  newobj      System.Func<System.String,System.Boolean>..ctor
IL_0014:  call        System.Linq.Enumerable.All

2 . myList.All(x=> LessThan16Char(x))

IL_001B:  ldarg.0     
IL_001C:  ldftn       UserQuery.<Main>b__0_0
IL_0022:  newobj      System.Func<System.String,System.Boolean>..ctor
IL_0027:  call        System.Linq.Enumerable.All

and extra generated method

<Main>b__0_0:
IL_0000:  ldarg.0     
IL_0001:  ldarg.1     
IL_0002:  call        UserQuery.LessThan16Char
IL_0007:  ret   

Usually they both do the same thing but in some scenarios they can be different. For example when you want to know the class which contains the method passed to the LINQ query and you are passing int.Parse instead of x => int.Parse(x). The second one is a method inside your class but first one is on a framework classes.

Upvotes: 2

weismat
weismat

Reputation: 7411

You can simply call it directly:

public Class1()
{
    var myList = new List<string>();
    var foo = myList.All(LessThan16Char);
}

if you need a second parameter than you will need the lambda:

public Class1()
{
    var myList = new List<string>();
    var foo = myList.All(l=>LessThan16Char(l,16));
}


public bool LessThan16Char(string input, int max)
{
    return (input.Length < max);
}

Upvotes: 6

Tanya Petkova
Tanya Petkova

Reputation: 155

You can write LessThan16Char as a string extension method:

    public static bool LessThan16Char(this string input)
    {
        return (input.Length < 16);
    }

and use it in your lambda expression:

    myList.All(x => x.LessThan16Char());

Upvotes: 0

Related Questions