使用表达式树访问对象、类型及成员(上):获取类型和成员的信息
2010-01-07 16:33
519 查看
当我们要打印一个字段或属性的值时,通常会采用如下的方法:
对于这种硬编码的坏处自然不言而喻,拼写错误等等是小事,一旦名称更改,四处查找替换无异于一场灾难。也许我们可以通过一个静态字段来代替硬编码,但如果要打印的字段过多,逐一添加静态字段也是相当痛苦的事情。
对此我们可以使用表达式树来解决:
在访问时,就无需再试用硬编码了:
表达式树给我们带来了智能感知和编译时语法错误提示,即使更改了字段或属性名称,也可以使用重构工具快速修复代码。
但是,在获取类型成员的数据时,我们还是会不可避免地使用硬编码字符串。我们可以使用typeof关键字来获取一个对象的类型而不必使用硬编码字符串,但是C#却没有提供相应的memberof。我们只能使用GetField或GetMethod等反射方法,将代表字段或方法名称的字符串作为参数传递进去。
如果SomeMethod方法包含重载方法,我们还不得不指定其参数。
这样的API使用起来实在是太不方便了。不但要使用无法在编译时检查的硬编码字符串,参数的个数、类型等等还会因为方法签名的修改而大受牵连。
好吧,让我们用表达式树来改变这一切。
这样,我们就可以像调用方法一样来获取MemberInfo了。
参考:
Getting Information About Objects, Types, and Members with Expression Trees
public class SomeClass { public string SomeField = "Some Field value"; } SomeClass someClass = new SomeClass(); Console.WriteLine("Some Field :" + someClass.SomeField);
对于这种硬编码的坏处自然不言而喻,拼写错误等等是小事,一旦名称更改,四处查找替换无异于一场灾难。也许我们可以通过一个静态字段来代替硬编码,但如果要打印的字段过多,逐一添加静态字段也是相当痛苦的事情。
对此我们可以使用表达式树来解决:
public static string GetName<T>(Expression<Func<T>> expr) { var member = expr.Body as MemberExpression; if (member != null) return member.Member.Name; throw new ArgumentException( "'" + expr + "': is not a valid expression for this method"); }
在访问时,就无需再试用硬编码了:
SomeClass someClass = new SomeClass(); Console.WriteLine("{0} : {1}", GetName(() => someClass.SomeField), someClass.SomeField);
表达式树给我们带来了智能感知和编译时语法错误提示,即使更改了字段或属性名称,也可以使用重构工具快速修复代码。
但是,在获取类型成员的数据时,我们还是会不可避免地使用硬编码字符串。我们可以使用typeof关键字来获取一个对象的类型而不必使用硬编码字符串,但是C#却没有提供相应的memberof。我们只能使用GetField或GetMethod等反射方法,将代表字段或方法名称的字符串作为参数传递进去。
Type type = typeof(SomeClass); MethodInfo method = type.GetMethod("SomeMethod");
如果SomeMethod方法包含重载方法,我们还不得不指定其参数。
Type type = typeof(SomeClass); MethodInfo method = type.GetMethod("SomeMethod", new Type[] { typeof(String) });
这样的API使用起来实在是太不方便了。不但要使用无法在编译时检查的硬编码字符串,参数的个数、类型等等还会因为方法签名的修改而大受牵连。
好吧,让我们用表达式树来改变这一切。
public static MemberInfo MemberOf<T>(Expression<Func<T>> e) { return MemberOf(e.Body); } // We need to add this overload to cover scenarios // when a method has a void return type. public static MemberInfo MemberOf(Expression<Action> e) { return MemberOf(e.Body); } private static MemberInfo MemberOf(Expression body) { var member = body as MemberExpression; if (member != null) return member.Member; var method = body as MethodCallExpression; if (method != null) return method.Method; throw new ArgumentException( "'" + body + "': not a member access"); }
这样,我们就可以像调用方法一样来获取MemberInfo了。
Console.WriteLine(MemberOf(() => someClass.SomeField)); // Prints System.String SomeField // To choose a particular method overload, // you simply show the usage of the method. Console.WriteLine(MemberOf(() => someClass.SomeMethod("Test"))); // Prints Void SomeMethod(System.String) Console.WriteLine(MemberOf(() => someClass.SomeMethod())); // Prints Void SomeMethod() Console.WriteLine(MemberOf(() => Console.Out)); // Prints System.IO.TextWriter Out
参考:
Getting Information About Objects, Types, and Members with Expression Trees
相关文章推荐
- 使用表达式树访问对象、类型及成员(下):获取对象和属性的值
- [翻译]使用表达式树获取对象、类型和成员的信息
- java基础-反射2(反射,反射操作对象,Class对象的使用,类型信息的获取)
- 使用Java HttpClient访问淘宝Ip查询接口获取具体位置信息
- java反射学习笔记(3)---使用Class来获取方法、成员变量、构造函数信息
- 使用 Unity(二):配置 Unity 、读取配置信息和获取对象
- 【python】获取对象的类型和信息
- [SharePoint]使用代码获取Document Set对象信息
- 反射机制的概述和字节码对象的获取方式 JavaBean的概述&BeanUtils的使用 反射操作构造方法、成员方法、成员属性
- 使用JAVA代码通过SSH访问远程windows,获取磁盘信息
- 使用 Unity(二):配置 Unity 、读取配置信息和获取对象
- 类和对象的存储、访问控制及类成员类型变化
- python使用unittest模块selenium访问斗鱼获取直播信息
- 使用SYSTEMINFO类获取UNITY3D运行设备的各类信息(CPU类型,显卡类型等)
- php面向对象不同类型成员访问方法 小结
- 使用表达式树和反射来访问对象属性的性能比较
- 使用EL表达式分别获取 某个 web 域 中的对象,访问 javabean 的属性、访问 list 集合、访问 map 集合、访问数组
- 使用表达式树和反射来访问对象属性的性能比较
- 反射机制的概述和字节码对象的获取,通过反射获取构造方法并使用;通过反射获取成员变量并使用;通过反射获取私有成员变量并使用;通过反射获取成员方法并使用
- JAVA进阶 面向对象程序设计——第4章 继承与多态【不同访问属性使子类在使用这些成员时不同】