C# 在变量中存储具有多个可能输出类型的Lambda表达式
问题: 我有一个包含排序按钮的标题的html表。数据在控制器上提取,并根据传递的路由值(字符串)使用C# 在变量中存储具有多个可能输出类型的Lambda表达式,c#,asp.net-mvc,lambda,C#,Asp.net Mvc,Lambda,问题: 我有一个包含排序按钮的标题的html表。数据在控制器上提取,并根据传递的路由值(字符串)使用OrderBy()进行排序。我目前正在使用一个巨大的switch语句,它需要对每个列进行col\u asc和col\u desc检查,以确定请求的排序方法。我想尽可能地减少这个值,然后添加一个然后再添加一个排序,它也将作为路由值传递 Func<MProduct,int> orderByLambda; switch (orderByColName) { case "asset_d
OrderBy()
进行排序。我目前正在使用一个巨大的switch语句,它需要对每个列进行col\u asc
和col\u desc
检查,以确定请求的排序方法。我想尽可能地减少这个值,然后添加一个然后再添加一个排序,它也将作为路由值传递
Func<MProduct,int> orderByLambda;
switch (orderByColName)
{
case "asset_desc":
//models = models.OrderByDescending(m => m.AssetId);
orderByLambda = m => m.AssetId; // this is test code
break;
case "asset_asc":
models = models.OrderBy(m => m.AssetId);
break;
case "location_desc":
models = models.OrderByDescending(m => m.Locations.Name);
break;
case "location_asc":
models = models.OrderBy(m => m.Locations.Name);
break;
...... So on and so forth ......
case "manufacturer_desc":
models = models.OrderByDescending(m => m.Models.Manufacturers.Name);
break;
case "manufacturer_asc":
models = models.OrderBy(m => m.Models.Manufacturers.Name);
break;
default:
models = models.OrderByDescending(m => m.AssetId);
break;
}
我被困的地方
到目前为止,这似乎是可行的(VisualStudio没有显示任何红色)。但是,由于必须将lambda变量声明为typeFunc
,因此无法传递数据类型不是int
的列。我怎样才能克服这个问题?有更好的办法吗?我正在研究动态
类型,但我不能100%确定该类型是否有效。您可以将顺序
设置为通用,但这意味着调用者需要指定列的类型
private IEnumerable<MProduct> Order<T>(List<MProduct> items, bool isDescending, Func<MProduct, T> orderByLambda)
{
if (isDescending)
{
return items.OrderByDescending(orderByLambda);
}
return items.OrderBy(orderByLambda);
}
您可以将Order
设置为泛型,但这意味着调用者需要指定列的类型
private IEnumerable<MProduct> Order<T>(List<MProduct> items, bool isDescending, Func<MProduct, T> orderByLambda)
{
if (isDescending)
{
return items.OrderByDescending(orderByLambda);
}
return items.OrderBy(orderByLambda);
}
这种方法有很多我喜欢的地方,但目前它有点让我不知所措。现在已经很晚了,我晚上没时间了,但我会深入研究,学一两样东西,然后在那一点之后标记为已被接受。谢谢@TylerSells很乐意提供帮助,如果我能提供任何信息,请毫不犹豫地询问:)这种方法有很多我喜欢的地方,但目前我有点不知所措。现在已经很晚了,我晚上没时间了,但我会深入研究,学一两样东西,然后在那一点之后标记为已被接受。谢谢@TylerSells很乐意帮忙,如果我能提供任何信息,请毫不犹豫地询问:)您可以将Func
更改为Func
,在您的情况下应该可以正常工作。您可以将Func
更改为Func
,在您的情况下应该可以正常工作。
private IEnumerable<MProduct> Order(List<MProduct> items, bool isDescending, Action<IApplyer<MProduct>> orderByLambda)
{
IApplyer<MProduct> applyer;
if (isDescending)
{
applyer = new OrderByApplyer<MProduct>(items);
}
else
{
applyer = new OrderDescendingByApplyer<MProduct>(items);
}
orderByLambda(applyer);
return applyer.Result;
}
// Usage
Order(items, true, a => a.Apply(o => o.Name));
Order(items, true, a => a.Apply(o => o.Age));
Dictionary<string, Action<IApplyer<MProduct>>> columns = new Dictionary<string, Action<IApplyer<MProduct>>>
{
["Name"] = a => a.Apply(o => o.Name),
["Age"] = a => a.Apply(o => o.Age),
};
Order(items, true, columns["Age"]);
//Implementation
interface IApplyer<TTarget>
{
void Apply<TColumn>(Func<TTarget, TColumn> orderBy);
IOrderedEnumerable<TTarget> Result { get; }
}
class OrderByApplyer<TTarget> : IApplyer<TTarget>
{
public OrderByApplyer(IEnumerable<TTarget> target)
{
this.Target = target;
}
public IEnumerable<TTarget> Target { get; }
public IOrderedEnumerable<TTarget> Result { get; set; }
public void Apply<TColumn>(Func<TTarget, TColumn> orderBy)
{
this.Result = this.Target.OrderBy(orderBy);
}
}
class OrderDescendingByApplyer<TTarget> : IApplyer<TTarget>
{
public OrderDescendingByApplyer(IEnumerable<TTarget> target)
{
this.Target = target;
}
public IEnumerable<TTarget> Target { get; }
public IOrderedEnumerable<TTarget> Result { get; set; }
public void Apply<TColumn>(Func<TTarget, TColumn> orderBy)
{
this.Result = this.Target.OrderByDescending(orderBy);
}
}
class ThenByApplyer<TTarget> : IApplyer<TTarget>
{
public ThenByApplyer(IOrderedEnumerable<TTarget> target)
{
this.Target = target;
}
public IOrderedEnumerable<TTarget> Target { get; }
public IOrderedEnumerable<TTarget> Result { get; set; }
public void Apply<TColumn>(Func<TTarget, TColumn> orderBy)
{
this.Result = this.Target.ThenBy(orderBy);
}
}
class ThenByDescendingByApplyer<TTarget> : IApplyer<TTarget>
{
public ThenByDescendingByApplyer(IOrderedEnumerable<TTarget> target)
{
this.Target = target;
}
public IOrderedEnumerable<TTarget> Target { get; }
public IOrderedEnumerable<TTarget> Result { get; set; }
public void Apply<TColumn>(Func<TTarget, TColumn> orderBy)
{
this.Result = this.Target.ThenByDescending(orderBy);
}
}