泛型List<>扩展方法简化及对象属性批量提取技术问询
简化泛型扩展方法,仅指定返回类型
针对你想要简化泛型List扩展方法的需求,我整理了一个更简洁的实现——只需要指定返回值类型T,不需要额外指定列表元素的类型,完美贴合你期望的selectAll<T>(this List<anyType>, ...)形式。
实现代码
我们可以基于非泛型的IEnumerable来编写扩展方法,这样能兼容任意类型的List(包括值类型和引用类型):
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Reflection; public static class ListExtensions { public static T[] SelectAll<T>(this IEnumerable list, string propertyName) { // 参数合法性校验 if (list == null) throw new ArgumentNullException(nameof(list), "源列表不能为null"); if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentException("属性名称不能为null或空白字符", nameof(propertyName)); var resultList = new List<T>(); foreach (var item in list) { if (item == null) { // 处理null元素:默认添加T类型的默认值,可根据需求修改为跳过/抛出异常 resultList.Add(default(T)); continue; } // 获取元素类型的指定公共实例属性 PropertyInfo prop = item.GetType().GetProperty( propertyName, BindingFlags.Public | BindingFlags.Instance ); if (prop == null) { throw new InvalidOperationException( $"类型'{item.GetType().FullName}'中未找到公共实例属性'{propertyName}'" ); } // 提取属性值并转换为目标类型T object propertyValue = prop.GetValue(item, null); resultList.Add((T)Convert.ChangeType(propertyValue, typeof(T), CultureInfo.InvariantCulture)); } return resultList.ToArray(); } }
使用示例
不管你的List存储的是自定义类、值类型还是其他对象,都可以直接调用这个方法,仅需指定返回类型:
// 自定义类示例 public class Person { public string Name { get; set; } public int Age { get; set; } } // 实际调用场景 List<Person> people = new List<Person> { new Person { Name = "Alice", Age = 30 }, new Person { Name = "Bob", Age = 25 } }; // 提取Name属性,返回string[] string[] names = people.SelectAll<string>("Name"); // 提取Age属性,返回int[] int[] ages = people.SelectAll<int>("Age"); // 值类型List示例(注意:值类型本身需存在指定属性,比如int没有Name属性,调用会抛异常) List<DateTime> dates = new List<DateTime> { DateTime.Now, DateTime.Now.AddDays(1) }; // 提取Date属性,返回DateTime[] DateTime[] dateValues = dates.SelectAll<DateTime>("Date");
关键说明
- 泛型简化:通过基于非泛型
IEnumerable扩展,我们不再需要指定列表元素的泛型参数,仅需关注返回值类型T,完全满足你的简化需求。 - 兼容性拉满:支持所有实现
IEnumerable的集合(包括List<T>、ArrayList等),不管元素是引用类型还是值类型。 - 健壮性保障:添加了参数校验、null元素处理和属性不存在的异常提示,调试时更清晰。
- 安全类型转换:使用
Convert.ChangeType配合InvariantCulture,确保属性值能安全转换为目标类型T,避免区域化导致的转换问题。
注意事项
- 如果列表中存在元素没有指定的公共实例属性,方法会抛出
InvalidOperationException,调用前需确保所有元素都包含该属性。 - 如果属性值无法转换为
T类型(比如把字符串"abc"转成int),Convert.ChangeType会抛出InvalidCastException,需确保类型转换的合理性。 - 针对null元素的处理逻辑可以根据你的需求修改,比如改成跳过null元素,或者直接抛出异常。
内容的提问来源于stack exchange,提问作者Ben Philipp
相关产品推荐
相关产品推荐

