C#中如何传递属性作为参数?高效提取指定属性方案咨询
在C#中高效提取集合对象指定属性的实现方式
嗨,这个需求在C#里有几种实用的实现方式,我给你拆解清楚,包括你提到的Expression方案:
1. 首选方案:用Func<Item, int>委托传递属性选择逻辑
这是最直接、性能也最好的方式,完全满足你的需求。我们可以把“属性引用”封装成一个Func<Item, int>类型的参数,它本质就是一个能从Item对象里取出指定int属性的方法。
实现代码如下:
public List<int> ParseData(List<Item> items, Func<Item, int> propertySelector) { // 预先分配和原集合一样的容量,避免List动态扩容的性能损耗 var result = new List<int>(items.Count); foreach (var item in items) { result.Add(propertySelector(item)); } return result; }
调用的时候超级简单,直接用Lambda表达式指定要提取的属性就行:
// 提取A属性 var aValues = ParseData(items, x => x.A); // 提取B属性 var bValues = ParseData(items, x => x.B);
这个方案的优势在于:几乎没有额外性能开销,Lambda会被编译成高效的委托;代码简洁易懂,日常开发里这绝对是首选。
2. 关于Expression方案:适合有额外元数据需求的场景
如果你的需求不只是单纯提取属性值,比如还需要获取属性的名称、做动态查询或者和ORM框架交互,那Expression才有用武之地。单纯提取属性的话,它的性能会比Func略差,因为需要编译表达式树。
如果要实现Expression版本,代码是这样的:
public List<int> ParseDataWithExpression(List<Item> items, Expression<Func<Item, int>> propertyExpression) { // 把表达式树编译成委托,如果多次调用同一个属性,记得缓存这个委托,避免重复编译 var selector = propertyExpression.Compile(); var result = new List<int>(items.Count); foreach (var item in items) { result.Add(selector(item)); } return result; }
调用方式和Func版本差不多:
var cValues = ParseDataWithExpression(items, x => x.C);
顺便说一句,如果你需要获取属性的名称,Expression就能派上用场了,比如:
var propertyName = ((MemberExpression)propertyExpression.Body).Member.Name; // 这里会得到"C"
3. 额外小技巧:用LINQ简化实现
如果是.NET 6及以上版本,你甚至不用自己写循环,直接用LINQ的Select方法一行搞定:
var aValues = items.Select(x => x.A).ToList();
这底层其实也是基于委托实现的,简洁又高效,如果你不需要封装成自定义的ParseData方法,直接用这个就好。
内容的提问来源于stack exchange,提问作者Ingweland
相关产品推荐
相关产品推荐

