bereitgestellt Lösung funktioniert, aber es ist nicht stark typisierte, so ist es auf Eigentum Umbenennung sinnvoll. Ein stark typisierter Ansatz kann verwendet werden, erfordert jedoch einige Einstellungen. Ein Teil des Setups ist jedoch so generisch, dass er wiederverwendet werden kann:
public class Order
{
public String OrderNo { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Misc { get; set; }
}
// clearly define properties that allow search
public enum OrderSearchableProp
{
OrderNo = 1,
FirstName = 2,
LastName = 3
}
class Program
{
// strongly-type requires an explicit mapping between property and its expression within the order object
static Dictionary<OrderSearchableProp, Expression<Func<Order, String>>> OrderSearchableMap = new Dictionary<OrderSearchableProp, Expression<Func<Order, string>>>()
{
{ OrderSearchableProp.OrderNo, o => o.OrderNo },
{ OrderSearchableProp.FirstName, o => o.FirstName },
{ OrderSearchableProp.LastName, o => o.LastName },
};
// this gets a PropertyInfo based from an Expression. It should be placed into a generic utility class
// credit goes to Daniel - http://stackoverflow.com/a/17116267/2780791
public static PropertyInfo GetPropertyFromExpression<T, TProp>(Expression<Func<T, TProp>> GetPropertyLambda)
{
MemberExpression Exp = null;
//this line is necessary, because sometimes the expression comes in as Convert(originalexpression)
if (GetPropertyLambda.Body is UnaryExpression)
{
var UnExp = (UnaryExpression)GetPropertyLambda.Body;
if (UnExp.Operand is MemberExpression)
{
Exp = (MemberExpression)UnExp.Operand;
}
else
throw new ArgumentException();
}
else if (GetPropertyLambda.Body is MemberExpression)
{
Exp = (MemberExpression)GetPropertyLambda.Body;
}
else
{
throw new ArgumentException();
}
return (PropertyInfo)Exp.Member;
}
public static IList<Order> getFilteredOrders(int propFilterValue, IList<Order> orders, String needle)
{
var filterValue = (OrderSearchableProp)propFilterValue;
var filterProp = OrderSearchableMap[filterValue];
var lowNeedle = needle?.ToLower() ?? String.Empty;
return orders.Where(o =>
{
var propInfo = GetPropertyFromExpression<Order, String>(filterProp);
var propValue = (String) propInfo.GetValue(o) ?? String.Empty;
return propValue.ToLower().Contains(lowNeedle);
}).ToList();
}
static void Main(string[] args)
{
// can be used to populate the combo items
// otherwise, not used in this example
OrderSearchableProp[] enumValues = (OrderSearchableProp[])Enum.GetValues(typeof(OrderSearchableProp));
// test orders
var orderList = new List<Order>()
{
new Order() { OrderNo = "1234ABC", FirstName = "George", LastName = "Taylor", Misc = "Extra information"},
new Order() { OrderNo = "AB10", FirstName = "Anonymous", LastName = "X", Misc = "No comment"}
};
// test OrderNo search
var searchProp = (int) OrderSearchableProp.OrderNo;
var foundOrders = getFilteredOrders(searchProp, orderList, "ABC");
// test FirstName search
searchProp = (int)OrderSearchableProp.FirstName;
foundOrders = getFilteredOrders(searchProp, orderList, "a");
// test LastName search with empty string
searchProp = (int)OrderSearchableProp.LastName;
foundOrders = getFilteredOrders(searchProp, orderList, "");
// empty return
searchProp = (int)OrderSearchableProp.OrderNo;
foundOrders = getFilteredOrders(searchProp, orderList, null);
}
}