简体   繁体   English

用于选择多个字段的C#Lambda表达式

[英]C# Lambda Expression for selecting multiple fields

Trying to encapsulate some logic in an extension method that will provide a ToSelectList method on a given IEnumerable, but I've hit a snag and I'm hoping someone can help to get me on the right track. 试图在扩展方法中封装一些逻辑,该扩展方法将在给定的IEnumerable上提供ToSelectList方法,但我遇到了麻烦,希望有人能帮助我步入正轨。

Essentially, I have one override that's fine. 本质上,我有一个很好的替代。 I have known fields that I use from a given base class, and the code looks as follows: 我知道给定基类使用的字段,代码看起来如下:

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

Not a problem. 没问题 Known fields. 已知领域。 The problem comes when I want to use specific fields from classes derived from BaseModel, but want to specify those from the calling code to make a more generic version of this method. 当我想使用从BaseModel派生的类中的特定字段,但想从调用代码中指定这些字段以使此方法更通用时,就会出现问题。

Essentially, I'm looking to use lambdas in the calling code to specify the two properties that I want to retrieve from the items in the list like so: 本质上,我希望在调用代码中使用lambda来指定要从列表中的项中检索的两个属性,如下所示:

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

So I'd have a method that looks like the following: 因此,我将拥有一种类似于以下内容的方法:

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() });
}

I'm trying to work out what I need to do to enable me to then use those within the expression used for the Select to use those fields as the values to assign to the properties of the SelectListItem . 我正在尝试找出所需做的事情,以使我能够在用于Select的表达式中使用这些表达式,以将这些字段用作分配给SelectListItem属性的值。 I'm guessing there must be something similar underneath the LINQ IEnumerable<T>.ToDictionary method where there's an expression for the key and another for the value. 我猜想在LINQ IEnumerable<T>.ToDictionary方法下面必须有类似的东西,其中有一个键的表达式和另一个值的表达式。

Is this even possible? 这有可能吗? Happy to cut my losses if it's not. 如果不是的话,很高兴削减我的损失。 At the moment, however, I'm struggling to get my head around what I'd need to pass to my ToSelectList method as parameters - is it an Expression<T> , a Func<T> , an Expression<Func<T>> ? 然而,目前,我正在努力了解需要传递给ToSelectList方法作为参数的内容-是Expression<T>Func<T> Expression<Func<T>> I don't mind admitting that I get quite lost in the expression evaluation stuff. 我不介意承认我在表达评估方面迷失了方向。

You could try the following 您可以尝试以下

   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)
                   });
    }

or 要么

   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)
                       });
        }

You don't need Expression<> here. 您在这里不需要Expression<> Plain Func<T, string> will do just fine. 普通的Func<T, string>就可以了。

Now, I can't really understand the this IEnumerable<BaseModel> list part, especially since you later do list.Cast<T>() . 现在,我真的无法理解this IEnumerable<BaseModel> list部分,尤其是因为您以后要做list.Cast<T>() It would be much cleaner to do this: 这样做会更清洁:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM