C#Lambda Expression用于选择多个字段

时间:2015-08-20 11:17:21

标签: c# linq lambda

尝试将一些逻辑封装在一个扩展方法中,该方法将在给定的IEnumerable上提供ToSelectList方法,但我遇到了障碍,我希望有人可以帮助我走上正确的轨道。

基本上,我有一个覆盖,没关系。我知道从给定基类使用的字段,代码如下所示:

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

不是问题。已知领域。当我想使用从BaseModel派生的类中的特定字段时,问题就出现了,但是想要从调用代码中指定那些字段以生成此方法的更通用版本。

基本上,我希望在调用代码中使用lambdas来指定我想从列表中的项目中检索的两个属性,如下所示:

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>还是{{1} }?我不介意承认我在表达式评估中迷失了方法。

2 个答案:

答案 0 :(得分: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)
                       });
        }

答案 1 :(得分: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