能否创建扩展方法,调用myObj.Amount.DoSomething()时获取属性名与值?
问题解答
直接通过 myObj.Amount.DoSomething() 这种调用方式,无法在DoSomething()方法内直接获取到属性名Amount。原因很简单:Amount的类型(比如int、decimal等值类型或引用类型)的实例本身不携带任何关于它所属属性的元数据,扩展方法只能拿到该属性的值,无法追溯它来自哪个属性。
不过我们可以通过两种方案实现“同时获取属性名和值”的需求,只是调用形式需要做一点调整:
方案一:基于表达式树的扩展方法
这种方式直接通过表达式指定属性,能可靠地获取属性名和对应值:
public static class Extensions { public static void DoSomething<TObj, TProp>(this TObj obj, Expression<Func<TObj, TProp>> propertySelector) { // 解析表达式获取属性名 var memberExpression = propertySelector.Body as MemberExpression; string propertyName = memberExpression.Member.Name; // 获取属性值 TProp propertyValue = propertySelector.Compile()(obj); // 这里可以使用属性名和值做逻辑处理 Console.WriteLine($"属性名:{propertyName},属性值:{propertyValue}"); } }
调用示例:
MyObj myObj = new MyObj { Amount = 100 }; myObj.DoSomething(x => x.Amount);
方案二:包装类+链式调用
如果想更接近你最初期望的链式调用形式,可以用包装类封装属性名和值,再给包装类加扩展方法:
// 包装类,存储属性名和对应值 public class PropertyWrapper<T> { public string PropertyName { get; } public T PropertyValue { get; } public PropertyWrapper(string name, T value) { PropertyName = name; PropertyValue = value; } } public static class Extensions { // 扩展方法:从对象中获取属性的包装实例 public static PropertyWrapper<TProp> GetProperty<TObj, TProp>(this TObj obj, Expression<Func<TObj, TProp>> propertySelector) { var memberExpression = propertySelector.Body as MemberExpression; string propertyName = memberExpression.Member.Name; TProp value = propertySelector.Compile()(obj); return new PropertyWrapper<TProp>(propertyName, value); } // 给包装类加扩展方法,实现DoSomething逻辑 public static void DoSomething<T>(this PropertyWrapper<T> wrapper) { Console.WriteLine($"属性名:{wrapper.PropertyName},属性值:{wrapper.PropertyValue}"); } }
调用示例:
MyObj myObj = new MyObj { Amount = 200 }; myObj.GetProperty(x => x.Amount).DoSomething();
内容的提问来源于stack exchange,提问作者Franky
相关产品推荐
相关产品推荐

