这样做的目的是避免编写大量的if()语句。
这是我目前的代码:
public override List<oAccountSearchResults> SearchForAccounts(oAccountSearchCriteria searchOptions)
{
List<oAccountSearchResults> results = Service.SearchForAccounts(searchOptions);
results.Sort((a1, a2) => a2.AccountNumber.CompareTo(a1.AccountNumber));
return results;
}
我想要做的是提供一个参数,告诉我要对哪个字段进行排序。然后动态更新我的排序条件,而不需要一堆if()语句,如:
public override List<oAccountSearchResults> SearchForAccounts(oAccountSearchCriteria searchOptions, string sortCriteria)
{
List<oAccountSearchResults> results = Service.SearchForAccounts(searchOptions);
if (sortCriteria == "AccountNumber")
{
results.Sort((a1, a2) => a2.AccountNumber.CompareTo(a1.AccountNumber));
}
else if (sortCriteria == "FirstName")
{
results.Sort((a1, a2) => a2.FirstName.CompareTo(a1.FirstName));
}
return results;
}
我希望在没有大约30个if()语句的情况下执行此操作,以获取可用的所有可排序条件。
任何和所有帮助将不胜感激。
使用解决方案进行编辑:
谢谢大家的回复。
大卫,你的接近工作,但我认为理查德的答案会有所改善。
这是我提出的最终解决方案。我使用David的框架作为示例和Richards实现:
using System;
using System.Collections.Generic;
namespace SortTest
{
class Program
{
static void Main(string[] args)
{
var results1 = Search(oObject => oObject.Value1);
foreach (oObject o in results1)
{
Console.WriteLine(o.Value1 + ", " + o.Value2);
}
Console.WriteLine(Environment.NewLine);
var results2 = Search(oObject => oObject.Value2);
foreach (oObject o in results2)
{
Console.WriteLine(o.Value1 + ", " + o.Value2);
}
Console.ReadLine();
}
public static List<oObject> Search<T>(Func<oObject, T> keyExtract) where T: IComparable
{
var results = new List<oObject>
{
new oObject {Value1 = "A 1", Value2 = "B 2"},
new oObject {Value1 = "B 1", Value2 = "A 2"}
};
results.Sort((a, b) => keyExtract(a).CompareTo(keyExtract(b)));
return results;
}
}
class oObject
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
}
答案 0 :(得分:3)
如果调用者可以提供表达式,它提取用于比较的值,则可以在比较函数中调用该委托:
public override List<oAccountSearchResults> SearchForAccounts<T>(
oAccountSearchCriteria searchOptions,
Func<oAccountSearchResults, T> keyExtract) where T : IComparable {
List<oAccountSearchResults> results = Service.SearchForAccounts(searchOptions);
results.Sort(a,b) => keyExtract(a).CompareTo(keyExtract(b)));
return results;
}
答案 1 :(得分:2)
你可以这样试试。我已经为测试目的创建了一个示例对象:
您可以从此处查看原始来源,但为了便于阅读而进行了清理:
http://msdn.microsoft.com/en-us/library/bb534966.aspx
首先在IEnumerable上创建一个扩展方法:
public static class EnumerableExtension
{
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> items, string property, bool ascending)
{
var myObject = Expression.Parameter(typeof (T), "MyObject");
var myEnumeratedObject = Expression.Parameter(typeof (IEnumerable<T>), "MyEnumeratedObject");
var myProperty = Expression.Property(myObject, property);
var myLambda = Expression.Lambda(myProperty, myObject);
var myMethod = Expression.Call(typeof (Enumerable), ascending ? "OrderBy" : "OrderByDescending",
new[] {typeof (T), myLambda.Body.Type}, myEnumeratedObject, myLambda);
var mySortedLambda =
Expression.Lambda<Func<IEnumerable<T>, IOrderedEnumerable<T>>>(myMethod, myEnumeratedObject).Compile();
return mySortedLambda(items);
}
}
这是我们的测试对象:
class oObject
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
然后在你的程序中你可以这样做:
static void Main(string[] args)
{
var results = new List<oObject>
{
new oObject {Value1 = "A", Value2 = "B"},
new oObject {Value1 = "B", Value2 = "A"}
};
IEnumerable<oObject> query = results.OrderBy("Value2", false);
foreach (oObject o in query)
{
Console.WriteLine(o.Value1 + ", " + o.Value2);
}
Console.WriteLine(Environment.NewLine);
IEnumerable<oObject> query2 = results.OrderBy("Value1", false);
foreach (oObject o in query2)
{
Console.WriteLine(o.Value1 + ", " + o.Value2);
}
Console.ReadLine();
}
您的结果将是:
查询1:
A,B
B,A
查询2:
B,A
A,B
答案 2 :(得分:1)
怎么样:
public override List<oAccountSearchResults> SearchForAccounts(oAccountSearchCriteria searchOptions, Comparsion<oAccountSearchResults> sortCriteria)
{
List<oAccountSearchResults> results = Service.SearchForAccounts(searchOptions);
results.Sort(sortCriteria);
return results;
}
然后你就像使用它一样:
SearchForAccounts(searchOptionsObject, (x,y) => x.Property.CompareTo(y.Property));
答案 3 :(得分:1)
使用String
到Comparer<oAccountSearchResults>
的地图,这样您就可以从字符串中找出代码术语中排序条件的含义。然后,您可以正常方式拨打Sort
。
private static readonly Dictionary<String,Comparer<oAccountSearchResults>>
SortOrders = new Dictionary<String,Comparer<oAccountSearchResults>>
{
{ "AccountNumber", (a1, a2) => a2.AccountNumber.CompareTo(a1.AccountNumber) },
{ "FirstName", (a1, a2) => a2.FirstName.CompareTo(a1.FirstName) }
// etc
};
public override List<oAccountSearchResults> SearchForAccounts(
oAccountSearchCriteria searchOptions, string sortCriteria)
{
Comparer< oAccountSearchCriteria> sortOrder;
if (!SortOrders.TryGetValue(sortCriteria, out sortOrder))
{
throw new ArgumentException("Unknown sort order " + sortCriteria);
}
List<oAccountSearchResults> results = Service.SearchForAccounts(searchOptions);
results.Sort(sortOrder);
return results;
}
答案 4 :(得分:0)
您是否考虑过简单地返回一个IEnumerable并允许cosumer确定他们希望如何对其进行排序。
Ayende Rahien在这里为这种行为提出了令人信服的案例:http://ayende.com/Blog/archive/2009/04/18/the-dal-should-go-all-the-way-to-ui.aspx
答案 5 :(得分:0)
执行.Net框架开发人员所做的事情,并让调用者告诉您如何排序。