使用反射根据字符串筛选数组元素,动态获取集合First/Last对应元素
动态根据字符串获取集合元素的实现方案
核心思路:先从传入的属性路径字符串中解析出需要调用的集合操作方法名,再根据方法名匹配对应的操作执行即可,有两种常用实现方式:
方案1:映射字典实现(推荐,性能高、易维护)
这种方式适合当前仅需要支持First、Last两个方法的场景,代码简单稳定,不会有反射的额外开销和异常风险。
// 示例传入的属性路径字符串 string inputPath = "Addresses.First()"; // 解析提取方法名 string methodName = inputPath.Split('.')[1].TrimEnd('(', ')'); var _propertyInfo = case.MainContact.GetType().GetProperty("Addresses"); XPCollection<BillingUnitContactAddress> buAddresses = (XPCollection<BillingUnitContactAddress>)_propertyInfo.GetValue(case.MainContact); // 定义操作映射字典 var addressOperations = new Dictionary<string, Func<XPCollection<BillingUnitContactAddress>, BillingUnitContactAddress>> { {"First", collection => collection.First()}, {"Last", collection => collection.Last()} }; // 安全调用逻辑 if (addressOperations.TryGetValue(methodName, out var getAddressFunc)) { BillingUnitContactAddress buAddress = getAddressFunc(buAddresses); // 执行后续业务逻辑 } else { // 处理不支持的方法名场景 }
方案2:反射调用LINQ方法(适合需要扩展更多操作的场景)
如果后续需要支持更多LINQ集合操作(如FirstOrDefault、LastOrDefault等),可以通过反射动态获取并调用对应方法,无需每次修改映射字典:
// 前面获取buAddresses的逻辑不变 var _propertyInfo = case.MainContact.GetType().GetProperty("Addresses"); XPCollection<BillingUnitContactAddress> buAddresses = (XPCollection<BillingUnitContactAddress>)_propertyInfo.GetValue(case.MainContact); string inputPath = "Addresses.First()"; string methodName = inputPath.Split('.')[1].TrimEnd('(', ')'); // 反射获取对应的LINQ泛型方法 var linqMethod = typeof(Enumerable) .GetMethods() .First(m => m.Name == methodName && m.GetParameters().Length == 1) .MakeGenericMethod(typeof(BillingUnitContactAddress)); // 执行方法获取结果 BillingUnitContactAddress buAddress = (BillingUnitContactAddress)linqMethod.Invoke(null, new object[] { buAddresses });
注意:
First、Last方法在集合为空时会抛出异常,如果你需要兼容空集合场景,可以将方法替换为FirstOrDefault、LastOrDefault,空集合时会返回对应类型的默认值。
内容的提问来源于stack exchange,提问作者Corey Dubois
相关产品推荐
相关产品推荐

