如何使用指定的模型属性创建填充List <selectlistitem>的通用方法?

时间:2015-12-16 01:50:54

标签: c# linq generics

作为通用存储库的一部分,我正在尝试创建一个通用方法,该方法将使用指定属性的值填充SelectListItems列表。

我想创建这样的东西:

public List<SelectListItem> AllAsSelectListItemsSpecifyProperties(Expression<Func<T, string>> valueProperty, Expression<Func<T, string>> textProperty, string selectedValue = "")
{
    return AllAsQueryable().Select(i => new SelectListItem()
    {
        Value = valueProperty.ToString(),
        Text = textProperty.ToString(),
        Selected = (selectedValue == valueProperty)
    })
    .ToList();
}

用法:

public List<SelectListItem> People()
{
    return AllAsSelectListItemsSpecifyProperties(m => m.ID, m => m.Name, "Ted");
}

希望结果:

我希望上面的用法返回List<> SelectListItems,例如:

List<SelectListItem>(){
    {Value: "1", Text: "Ted", Selected: true},
    {Value: "2", Text: "Sam", Selected: false},
    {Value: "3", Text: "Tracy", Selected: false}
};

更新

我想我可能一直不清楚。或者做错了。

下面的答案是返回一个这样的对象:

List<SelectListItem>(){
    {Value: "ID", Text: "Name", Selected: true},
    {Value: "ID", Text: "Name", Selected: false},
    {Value: "ID", Text: "Name", Selected: false}
};

是我尝试做的事情,而且 - 如果是的话 - 是否有人能够指出我做错了什么?

2 个答案:

答案 0 :(得分:1)

要使用表达式获取属性值,您可以编译表达式,然后您将拥有一个Func,并且您可以执行该Func来获取值,如下所示:

public List<SelectListItem> AllAsSelectListItemsSpecifyProperties(Expression<Func<T, string>> valueProperty, Expression<Func<T, string>> textProperty, string selectedValue = "")
{
    return AllAsQueryable().Select(i => new SelectListItem()
    {
        Value = GetPropertyValue(valueProperty),
        Text = GetPropertyValue(textProperty),
        Selected = (selectedValue == valueProperty)
    })
    .ToList();
}

private string GetPropertyValue(Expression<Func<T, string>> expression)
{
    return expression.Compile()(this).ToString();
}

答案 1 :(得分:1)

您可以编写如下所示的方法,以从Expression中获取值以创建List。

public List<SelectListItem> AllAsSelectListItemsSpecifyProperties(Expression<Func<T, string>> valueProperty, Expression<Func<T, string>> textProperty, string selectedValue = "")
{
    return AllAsQueryable().Select(i => new SelectListItem()
    {
        Value = GetValue(valueProperty.Body as MemberExpression).ToString(),
        Text = GetValue(textProperty.Body as MemberExpression).ToString(),
        Selected = (selectedValue == valueProperty)
    })
    .ToList();
}


private object GetValue(MemberExpression member)
{
    var objectMember = Expression.Convert(member, typeof(object));

    var getterLambda = Expression.Lambda<Func<object>>(objectMember);

    var getter = getterLambda.Compile();

    return getter();
}