2015-08-20 2 views
0

Попытка инкапсулировать некоторую логику в методе расширения, который предоставит метод ToSelectList для данного IEnumerable, но я попал в ловушку, и я надеюсь, что кто-то может помочь мне правильном пути.C# Lambda Expression для выбора нескольких полей

По существу, у меня есть одно переопределение, это нормально. Я знаю поля, которые я использую из данного базового класса, и код выглядит следующим образом:

public static IEnumerable<SelectListItem> ToSelectList(this IEnumerable<BaseModel> list) 
{ 
    return list.Select(t => new SelectListItem { Text = t.Description, Value = t.Id.ToString() }); 
} 

Не проблема. Известные поля. Проблема возникает, когда я хочу использовать определенные поля из классов, основанных на BaseModel, но хочу указать их из вызывающего кода, чтобы сделать более общую версию этого метода.

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

myEnumerable.ToSelectList(textSelector => textSelector.Id.ToString(), valueSelector => valueSelector.DisplayName); 

Так что я должен был бы метод что выглядит следующим образом:

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<BaseModel> list, [DON'T KNOW WHAT GOES HERE] textExpression, [DON'T KNOW WHAT GOES HERE] valueExpression) 
{ 
    return list.Cast<T>().Select(t => new SelectListItem { Text = textExpression(t), Value = valueExpression(t).ToString() }); 
} 

Я пытаюсь выяснить, что мне нужно сделать, чтобы я мог затем использовать те, в выражении, используемом для Select, чтобы использовать эти поля в качестве значения для назначения на свойства SelectListItem. Я предполагаю, что в методе LINQ IEnumerable<T>.ToDictionary должно быть что-то похожее, где есть выражение для ключа, а другое для значения.

Возможно ли это? Счастлив сократить мои потери, если это не так. На данный момент, однако, я изо всех сил пытаюсь понять, что мне нужно передать моему методу ToSelectList в качестве параметров - это Expression<T>, Func<T>, Expression<Func<T>>? Я не возражаю, признавая, что я очень теряюсь в материалах оценки выражения.

ответ

1

Вам не нужно Expression<> здесь. Обычный Func<T, string> будет делать все отлично.

Теперь, я не могу понять часть this IEnumerable<BaseModel> list, тем более, что вы позже сделали list.Cast<T>(). Было бы намного чище сделать это:

IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T>, 
    Func<T, string> textProvider, 
    Func<T, string> idProvider) 
    where T : BaseModel 
2

Вы можете попробовать следующее

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<BaseModel> list, Expression<Func<T, string>> textExpression, Expression<Func<T, string>> valueExpression) 
     { 
      var textFunc = textExpression.Compile(); 
      var valueFunc = valueExpression.Compile(); 

      return list.Select(t => new SelectListItem 
        { 
         Text = textFunc(t), 
         Value = valueFunc(t) 
        }); 
    } 

или

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<BaseModel> list, Func<T, string> textFunc, Func<T, string> valueFunc) 
     { 
      return list.Select(t => new SelectListItem 
         { 
          Text = textFunc(t), 
          Value = valueFunc(t) 
         }); 
     }