C# 使用类属性对列表进行分组和拆分
我有下面的代码,我真的很想对其进行泛化,这样就不必根据字段调用相同的LINQ语句 是否有方法将此switch语句向上移动到ItemViewModel,并调用以检索泛型属性以根据其字符串名称执行分组C# 使用类属性对列表进行分组和拆分,c#,linq,grouping,C#,Linq,Grouping,我有下面的代码,我真的很想对其进行泛化,这样就不必根据字段调用相同的LINQ语句 是否有方法将此switch语句向上移动到ItemViewModel,并调用以检索泛型属性以根据其字符串名称执行分组 private List<List<ItemViewModel>> SplitItemList(List<List<ItemViewModel>> ItemLists, string groupingField) {
private List<List<ItemViewModel>> SplitItemList(List<List<ItemViewModel>> ItemLists,
string groupingField)
{
var newItemLists = new List<List<ItemViewModel>>();
foreach (var itemList in ItemLists)
{
var newList = new List<List<ItemViewModel>>();
switch (groupingField)
{
case "problem_description":
newList = itemList
.GroupBy(a => a.ProblemDescription)
.Select(x => x.ToList())
.ToList();
break;
case "sw_code":
newList = itemList
.GroupBy(a => a.SoftwareCode)
.Select(x => x.ToList())
.ToList();
break;
case "hw_code":
newList = itemList
.GroupBy(a => a.HardwareCode)
.Select(x => x.ToList())
.ToList();
break;
case "etc":
break;
default:
break;
}
newItemLists.AddRange(newList);
}
return newItemLists;
}
在循环中,尝试动态创建lambda:
public static Func<TIn, TOut> CreateGetter<TIn, TOut>(string propertyName)
{
var input = Expression.Parameter(typeof(TIn));
var expression = Expression.Property(input, typeof(TIn).GetProperty(propertyName));
return Expression.Lambda<Func<TIn, TOut>>(expression, input).Compile();
}
使用查找表怎么样?Dunken的可能重复:使用GroupBySelector听起来很有趣,但我找不到任何好的例子来说明如何进行此操作。你能给我指一个吗?是的,这就是问题所在——不是,因此有了switch语句。我想在ItemViewModel中添加一些东西来处理这个问题,但我不确定是什么。不过,我确实喜欢Lamda表达式,我必须仔细阅读它-为您的解决方案干杯。为什么不尝试在函数上添加自定义属性,如:[MyAttributeproblem_description]公共字符串ProblemDescription{get;set;}然后,您可以维护一个通过反射从上述属性获得的友好名称字典,以便将反射导致的cpu成本降到最低,并如上所述使用动态linq。这听起来是一个不错的解决方案,但您是否有机会为我举一个很好的例子?我对C相当陌生。
var list = new List<Tuple<string, string>>();
var getter = DynamicLinq.CreateGetter<Tuple<string, string>, string>("Item1");
var query = list.GroupBy(getter).Select(x => x.ToList());
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class FriendlyNameAttribute : Attribute
{
public string FriendlyName { get; set; }
public FriendlyNameAttribute(string friendlyName)
{
FriendlyName = friendlyName;
}
}
public class ItemViewModel
{
private static readonly IDictionary<string, string> PropertyMap;
static ItemViewModel()
{
PropertyMap = new Dictionary<string, string>();
var myType = typeof (ItemViewModel);
foreach (var propertyInfo in myType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (propertyInfo.GetGetMethod() != null)
{
var attr = propertyInfo.GetCustomAttribute<FriendlyNameAttribute>();
if (attr == null)
continue;
PropertyMap.Add(attr.FriendlyName, propertyInfo.Name);
}
}
}
public static string GetPropertyMap(string groupingField)
{
string propName;
PropertyMap.TryGetValue(groupingField, out propName);
return propName; //will return null in case map not found.
}
[FriendlyName("problem_description")]
public string ProblemDescription { get; set; }
public string OtherProperty { get; set; } // will not be in map
}
var x = ItemViewModel.GetPropertyMap("problem_description");