【发布时间】:2016-06-03 06:35:07
【问题描述】:
我想知道这种方法是否可以做得更好。我需要过滤作为字符串传入的成员名称上的通用列表。我的想法是将通用列表转换为动态列表,然后将 expandoObject 转换为 Dictionary 并检查成员名称是否存在。最后,使用 JsonSerializer 将动态列表转换回通用列表。您对更好的实施有何想法?反射?动态 LINQ(Scott Guthrie 在 2008 年做了一些工作)?表达式树?
public static IEnumerable<T> FilterListByStringPropertyName<T>(this IEnumerable<T> genericList, int? enumId, string enumFieldName)
{
if (string.IsNullOrEmpty(enumFieldName))
{
throw new NullReferenceException("FilterByEnum: enumFieldName cannot be empty");
}
if (enumId == null)
{
//skip method as no filtering needed
return genericList;
}
if (genericList.Count() == 0)
{
return genericList;
}
List<T> @return = new List<T>();
List<dynamic> dynamicList = new List<dynamic>();
//fill the dynamic list from generic list
foreach (var genericItem in genericList)
dynamicList.Add(genericItem.ToDynamic());
var first = dynamicList.FirstOrDefault();
//initialise filteredDynamicList
IEnumerable<dynamic> filteredDynamicList = dynamicList;
if (enumId != null)
{
//ExpandoObject implements IDictionary<string, object>, so cast as that to check what the fields are
if (!((IDictionary<string, object>)first).ContainsKey(enumFieldName))
{
throw new KeyNotFoundException(string.Format("{0} is not a member of {1}", enumFieldName, genericList.GetType().GetGenericArguments()[0]));
}
//filter by the AddressStatus enum (as int)
filteredDynamicList = dynamicList.Where(a => (int)((IDictionary<string, object>)a)[enumFieldName] == enumId.Value);
}
//convert from dynamic back to to generic
var json = Newtonsoft.Json.JsonConvert.SerializeObject(filteredDynamicList);
@return = Newtonsoft.Json.JsonConvert.DeserializeObject<List<T>>(json);
return @return;
}
【问题讨论】: