C#如何创建可复用方法访问任意对象的指定属性?
嘿,我完全懂你的需求——就是想搞一个通用方法,能拿到任意对象的指定属性值,不用每次都写重复的代码块,对吧?这场景太常见了,我给你两种实用的实现方案,你可以根据自己的性能需求和复杂度偏好来选:
方案1:使用反射实现(简单直接)
反射是最直接的方式,不用额外复杂的逻辑,几行代码就能搞定。咱们直接看代码:
public static object GetPropertyValue(object parent, string propertyName) { if (parent == null) throw new ArgumentNullException(nameof(parent)); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException(nameof(propertyName)); // 获取指定属性的信息 var propertyInfo = parent.GetType().GetProperty(propertyName); if (propertyInfo == null) throw new ArgumentException($"属性 {propertyName} 在类型 {parent.GetType().Name} 中不存在"); // 获取属性值并返回 return propertyInfo.GetValue(parent); }
使用示例
比如你要拿User对象的UserID:
User myUser = new User { UserID = 123 }; object userIdValue = GetPropertyValue(myUser, "UserID"); // 如果需要转成int类型,可以直接强转:int userId = (int)userIdValue;
这个方案的优点是实现简单,上手快;缺点是反射的性能相对低一些,如果你的代码会被频繁调用(比如循环里成千上万次调用),可能会有性能瓶颈。
方案2:使用表达式树实现(性能更优)
如果追求更好的性能,表达式树是个不错的选择——它可以把属性访问逻辑编译成委托,后续调用的时候就和直接访问属性差不多快。咱们来看泛型版本的实现,还能直接返回指定类型的结果,不用强转:
public static Func<TParent, TProperty> CreatePropertyGetter<TParent, TProperty>(string propertyName) { // 构建参数表达式:代表输入的父对象 var parameter = Expression.Parameter(typeof(TParent), "parent"); // 构建属性访问表达式:parent.PropertyName var propertyAccess = Expression.Property(parameter, propertyName); // 把表达式编译成委托 var getter = Expression.Lambda<Func<TParent, TProperty>>(propertyAccess, parameter).Compile(); return getter; }
使用示例
还是拿User对象的UserID举例:
// 先编译一次获取UserID的委托 var getUserID = CreatePropertyGetter<User, int>("UserID"); // 之后每次调用直接用这个委托就行 User myUser = new User { UserID = 123 }; int userId = getUserID(myUser);
这个方案的优点是性能接近直接访问属性,适合频繁调用的场景;缺点是需要提前编译委托,而且需要指定泛型类型(不过也可以写非泛型版本,返回object,和反射类似但性能更好)。
额外小提示
如果你用的是.NET Core 3.0+或者.NET 5+,还可以用System.Linq.Expressions里的更简洁写法,或者甚至用System.Reflection.Emit来动态生成IL代码,但上面两种方案已经能覆盖绝大多数场景了。
内容的提问来源于stack exchange,提问作者Aousaf Rashid
相关产品推荐
相关产品推荐

