OrderBy keySelector с различными типами данных на TKey - PullRequest
2 голосов
/ 22 октября 2019

Мне нужен метод, который возвращает keySelector, который можно использовать при вызове выражения OrderBy. Проблема в том, что keySelector является универсальным делегатом, и я хотел бы, чтобы метод возвращал keySelectors с различными типами данных на TKey:

Func<TSource,TKey> keySelector

Я хотел бы добиться этого, но вместо использования лямбда-выражений используется методкоторый возвращает keySelector (TKey = string или int):

IEnumerable<Person> orderedByFirstName = persons.OrderBy(p => p.FirstName);
IEnumerable<Person> orderedByAge = persons.OrderBy(p => p.Age);

Возможно ли иметь метод, который каким-то образом возвращает keySelectors с различными типами на TKey? Невозможно вернуть лямбда-выражения, но что-то в этом роде ...

Пока метод возвращает только keySelectors типа data string, все работает нормально:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class Behavior
{
    public virtual string GetOrderByKeySelector(Person p)
    {
        return p.FirstName;
    }
}

public class SpecializedBehavior : Behavior
{
    public override string GetOrderByKeySelector(Person p)
    {
        return p.LastName;
    }
}

List<Person> persons = new List<Person>
{
    new Person{Age=10, FirstName="Pelle", LastName="Larsson"},
    new Person{Age=90, FirstName="Nils", LastName="Nilsson"}, 
    new Person{Age=15, FirstName="Olle", LastName="Johansson"},
    new Person{Age=30, FirstName="Kalle", LastName="Svensson"}
};

Используется какэто:

SpecializedBehavior behavior = new SpecializedBehavior();
IEnumerable<Person> orderedResult = persons.OrderBy(behavior.GetOrderByKeySelector);

Ответы [ 2 ]

1 голос
/ 22 октября 2019

А как насчет того, чтобы взять коллекцию в метод?

void Main()
{
    SpecializedBehavior behavior = new SpecializedBehavior();
    IEnumerable<Person> orderedResult = behavior.Sort(persons);
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class Behavior
{
    public virtual IEnumerable<Person> Sort(IEnumerable<Person> persons)
    {
        return persons.OrderBy(p => p.FirstName);
    }
}

public class SpecializedBehavior : Behavior
{
    public override IEnumerable<Person> Sort(IEnumerable<Person> persons)
    {
        return persons.OrderBy(p => p.Age);
    }
}


List<Person> persons = new List<Person>
{
    new Person{Age=10, FirstName="Pelle", LastName="Larsson"},
    new Person{Age=90, FirstName="Nils", LastName="Nilsson"},
    new Person{Age=15, FirstName="Olle", LastName="Johansson"},
    new Person{Age=30, FirstName="Kalle", LastName="Svensson"}
};
0 голосов
/ 22 октября 2019

Этот ответ только для иллюстрации комментария @ LasseVågsætherKarlsen, и вся заслуга должна быть передана ему:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class PersonByFirstNameComparer : IComparer<Person>
{
    public int Compare(Person left, Person right) =>
        left.FirstName.CompareTo(right.FirstName);
}

public class Behavior
{
    public virtual IComparer<Person> GetComparer() => PersonByFirstNameComparer();
}

public class PersonByLastNameComparer : IComparer<Person>
{
    public int Compare(Person left, Person right) =>
        left.LastName.CompareTo(right.LastName);
}

public class SpecializedBehavior : Behavior
{
    public override IComparer<Person> GetComparer() => new PersonByLastNameComparer();
}

, который можно использовать следующим образом:

public static void Main()
{
    var people = new List<Person>
    {
        new Person{Age=10, FirstName="Pelle", LastName="Larsson"},
        new Person{Age=90, FirstName="Nils", LastName="Nilsson"}, 
        new Person{Age=15, FirstName="Olle", LastName="Johansson"},
        new Person{Age=30, FirstName="Kalle", LastName="Svensson"}
    };

    var standardBehavior = new Behavior();
    IEnumerable<Person> orderedPeople1 = 
        people.OrderBy(p => p, standardBehavior.GetComparer());

    foreach (Person p in orderedPeople1)
    {
        Console.WriteLine($"{p.FirstName} {p.LastName}");
    }

    var specializedBehavior = new SpecializedBehavior();
    IEnumerable<Person> orderedPeople2 = 
        people.OrderBy(p => p, specializedBehavior.GetComparer());

    foreach (Person p in orderedPeople2)
    {
        Console.WriteLine($"{p.FirstName} {p.LastName}");
    }
}

Ссылка на скрипку

...