Why does passing lambda parameter into a method not work?

69 Views Asked by At

Given this code:

class Pet
{
    public string Name { get; set; }
    public int Age { get; set; }
}

public static void OrderByEx1()
{
    Pet[] pets = { new Pet { Name="Barley", Age=8 },
                   new Pet { Name="Boots", Age=4 },
                   new Pet { Name="Whiskers", Age=1 } };

    IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age == 8 ? 0 : 1);

    foreach (Pet pet in query)
    {
        Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
    }
}

Is it possible to extract pet => pet.Age == 8 ? 0 : 1 into its own method and do some conditonal statements based on pet.Age without using ternary operations?

To add to this, I have tried doing something like this:

IEnumerable<Pet> query = pets.OrderBy(pet => NewMethod(pet));

And define the method as such:

private static Expression<Func<Pet, int>> NewMethod(Pet pet)
{
    if(pet.Age == 8)
        return 0;
    else
        return 1;
}

But that does not seem to work as intended.

But doing this:

IEnumerable<Pet> query = pets.OrderBy(NewMethod);

And this, works fine:

private static Expression<Func<Pet, int>> NewMethod(Pet pet)
{
    return pet => pet.Age == 8 ? 0 : 1;
}
1

There are 1 best solutions below

10
Ryan Wilson On

You can create a class which implements IComparer<T> where T is your class type Pet and then pass an instance of this into OrderBy:

public class MyPetAgeComparer : IComparer<Pet>
{
     public int Compare(Pet a, Pet b)
     {
         //Add your comparison logic here
     }
}

In code usage:

public static void OrderByEx1()
{
     Pet[] pets = { new Pet { Name="Barley", Age=8 },
               new Pet { Name="Boots", Age=4 },
               new Pet { Name="Whiskers", Age=1 } };
     //Here you would pass in an instance of your custom
     //comparer class as the second parameter of OrderBy
     IEnumerable<Pet> query = pets.OrderBy(pet => pet, new MyPetAgeComparer());

     foreach (Pet pet in query)
     {
         Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
     }
}

More information on OrderBy - system.linq.enumerable.orderby