повторное использование вызова метода внутри Func / лямбда-выражения

#c# #lambda #func

#c# #лямбда #функция

Вопрос:

Сначала позвольте мне сказать, что я не уверен, имеет ли название этого вопроса какой-либо смысл, но я не уверен, как сформулировать мою проблему.

У меня есть класс, определенный как

 public static class NaturalSort<T>
  

У этого класса есть метод

 public static IEnumerable<T> Sort(IEnumerable<T> list, Func<T, String> field)
  

По сути, он выполняет естественную сортировку в некотором списке, заданном функцией, которая возвращает значение для сортировки. Я использовал это для всего, для чего я хочу выполнить естественную сортировку.

Обычно я бы сделал что-то вроде

 sorted = NaturalSort<Thing>.sort(itemList, item => item.StringValueToSortOn)
  

Теперь у меня есть случай, когда значение, по которому я хочу отсортировать, не является полем элемента, а является вызовом некоторого метода

Что-то вроде

 sorted = NaturalSort<Thing>.sort(itemList, item => getValue(item))
  

Теперь, что, если я получу значение, возвращающее объект вместо строки. и мне нужно выполнить некоторую условную логику, чтобы получить мое строковое значение

 sorted = NaturalSort<Thing>.sort(itemList, item => getValue(item).Something == null ? getValue(item).SomethingElse : getValue(item).SomeotherThing)
  

Это сработало бы, за исключением того, что вызов GetValue является дорогостоящим, и я не хочу вызывать его 3 раза. Есть ли какой-нибудь способ, которым я могу вызвать его один раз внутри выражения?

Ответ №1:

Да, лямбда-выражения могут содержать несколько строк кода.

 item =>
{
  var it = getvalue(item);
  return it.Something == null ? it.SomethingElse : it.SomeotherThing;
}
  

Убедитесь, что вы возвращаете значение в этом синтаксисе при использовании Func<T> делегата, хотя это обрабатывается неявно в кратком синтаксисе, вы должны сделать это самостоятельно в многострочном синтаксисе.

Кроме того, вы должны сделать свой Sort метод методом расширения, вам также не нужен параметр type в классе, просто используйте

 public static IEnumerable<T> Sort<T>(this IEnumerable<T> list, Func<T, String> field)
  

Ответ №2:

@Femaref равен 100%, мне просто интересно, почему вы не пошли бы с

 sorted = NaturalSort<Thing>.sort(itemList, item => getValue(item))
         .Select(item => item.Something == null ? item.SomethingElse : item.SomeotherThing)
  

Комментарии:

1. Это недопустимо, поскольку GetValue(item) не возвращает строку

2. он хочет выполнить сортировку по члену item , поэтому ему нужен этот член в вызове сортировки.

3. doh. по какой-то причине это пришло мне в голову, это было преобразование для lambda. не обращайте внимания на мои безумные разговоры…