2014-02-06 3 views
0

Я пытаюсь создать метод расширения с дженериков, в котором вы получите список независимо от класса, к примеру:выражение Изменить лямбда в методе расширения

class User 
{ 
    public string name {get;set;} 
    public int age {get;set;} 
    public string lastLogon {get;set;} 
} 

Я пытаюсь построить expresion, в котором вы переходите к методу расширения IEnumerable и указываете, что является свойством строковой даты. (В этом случае lastLogon)

Без метода расширения Это должно быть что-то вроде:

userList.OrderBy(x => Convert.ToDateTime(x.lastLogon)); 

Это то, что я сделал до сих пор:

public static IEnumerable<TSource> OrderEnumerablebyDatetimeString<TSource,TKey>(
      this IEnumerable<TSource> input, Func<TSource, TKey> funcexpr) 
     { 
      //modify expression to get the date field and modify the lambda expr 
      Expression<Func<TSource, TKey>> expr = ??? 

      return input.OrderBy(funcexpr); 

     } 

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

userList.OrderEnumerablebyDatetimeString(x => x.lastLogon); 
+0

использование 'Expression > funcexpr' вместо' Func funcexpr' – Grundy

+0

Grundy прав, если это Linq-to-SQL. –

+0

@JeppeStigNielsen Я имею в виду, что после изменения вызова 'Compile' и использовать с' IEnumerable' – Grundy

ответ

3

Это то, что у меня есть для вас:

public static IEnumerable<TSource> OrderEnumerablebyDatetimeString<TSource>(
this IEnumerable<TSource> input, Func<TSource, string> funcexpr) 
{ 
    Func<TSource, DateTime> expr = (x=>Convert.ToDateTime(funcexpr(x))); 

    return input.OrderBy(expr); 

} 

Обратите внимание, что я удалил и изменил некоторые общие параметры, чтобы более точно отразить то, что у вас есть. Вы сказали, что вы всегда проходите в цепочке, так что удовольствие, которое вы проходите, должно всегда возвращать строку. Аналогично, выражение, которое вы создаете для своего orderby, всегда будет возвращать DateTime, поэтому я жестко запрограммировал это.

Ключевой бит, конечно, вызывает переданный Func, чтобы получить строку даты от объекта.

Чтобы объяснить это более подробно (в соответствии с запросом в комментариях), funcexpr(x) вызывает функцию func, с которой вы передали x в качестве параметра. Это похоже на вызов любого другого метода, кроме вашего метода, в переменной. Специфически func объявлен как метод, который принимает объект и возвращает string. В этом случае строка является строкой даты из объекта, который в нашем примере является пользователем. Таким образом, funcexpr(x) вернет строку даты, которая затем преобразуется в DateTime путем преобразования, как и следовало ожидать.

Я должен также отметить для полноты, что это было выполнено и протестировано в контексте Linq to Objects. Что я предполагаю, так как вы говорите о работе с List<User>, это дело.

Также здесь есть ссылка на рабочий образец, включая строку сортировки, а доказать его работает должным образом: http://dotnetfiddle.net/r3Lq0P

+0

'IEnumerable' расширениям нужно' Func' не 'Expression' – Grundy

+0

@Grundy: может потребоваться слишком сильная работа приведенный выше код был протестирован и работает в linqpad. Вы правы, что это не нужно, хотя это будет чище, чтобы удалить его. – Chris

+0

Просто заметил, что мое тестирование было шокирующим, хотя я не использовал expr. ;-) – Chris

Смежные вопросы