当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 谈.NET反射的封装

ASP.NET
使用函数传递参数来执行相应的数据库操作
如何实现在窗体和窗体之间进行传递数据
ASP.NET中文显示之两种解决方法
ASP.NET、JSP及PHP之间的抉择
ASP.NET 2.0发送电子邮件中存在的问题
谈谈HtmlControl与WebControl的区别与用途
从ASP.NET 1.1升级到ASP.NET 2.0要考虑的Cookie问题
通过系统配置来提高ASP.NET应用程序的稳定性
妙用ASP2.0中的URL映射改变网址
AJAX实现web页面中级联菜单的设计
ASP.NET跨页面传值技巧总结
再议ASP.NET DataGrid控件中的“添加新行”功能
Geometry 对象浅析
重构CollapsibleSplitter
如何利用.NET Framework使用RSS feed
ASP.NET获取IP与MAC地址的方法
在ASP.NET 2.0中使用样式、主题和皮肤
ASP.NET中为GridView添加删除提示框
ASP.NET 2.0,无刷新页面新境界
看看一个.net版对话框控件

ASP.NET 中的 谈.NET反射的封装


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 51 ::
收藏到网摘: n/a

.NET反射提供了在运行时获取对象类型元数据的途径,使程序可以动态地调用对象的属性、方法。动态性带来的代价是反射调用不像基于静态类型的直接调用那样简洁,且缺乏类型检查机制,失去了IDE智能提示,容易出错;于是,不少朋友尝试对.NET反射进行封装。这个话题是仁者见仁,智者见智,这里我也谈谈自己对.NET反射封装的思路,请先看下面的示例代码:
  static void Main(string[] args)
  {
  Person liu = new Person("liu", 26);
  Reflector reflector = new Reflector(liu);
  //获取属性
  string name = reflector.Property<string>("Name");
  int age = reflector.Property<int>("Age");
  Console.WriteLine(name + " " + age);
  //修改属性
  age = reflector.SetProperty<int>("Age", 27);
  Console.WriteLine(name + " " + age);
  //获取过程
  Proc<string> sayHello = reflector.Proc<string>("SayHello");
  sayHello("Ling");
  //获取函数
  Func<int> getAge = reflector.Func<int>("GetAge");
  age = getAge();
  Console.WriteLine(age);
  Console.ReadLine();
  }
  public class Person
  {
  private string name;
  private int age;
  public Person(string name, int age)
  {
  this.name = name;
  this.age = age;
  }
  public string Name
  {
  get { return name; }
  }
  public int Age
  {
  get { return age; }
  set { age = value; }
  }
  public void SayHello(string who)
  {
  Console.WriteLine("Say Hello to " + who);
  }
  public int GetAge()
  {
  return age;
  }
  }
  相信您已经从代码看出了封装的思路:利用泛型和泛型委托为动态的反射添加静态的类型约束。下面我们就来简单看一下Reflector实现的关键部分:
  public delegate void Proc();
  public delegate void Proc<T1>(T1 arg1);
  public delegate void Proc<T1, T2>(T1 arg1, T2 args);
  public delegate void Proc<T1, T2, T3>(T1 arg1, T2 args, T3 arg3);
  public delegate void Proc<T1, T2, T3, T4>(T1 arg1, T2 args, T3 arg3, T4 arg4);
  public delegate void Proc<T1, T2, T3, T4, T5>(T1 arg1, T2 args, T3 arg3, T4 arg4, T5 arg5);
  public delegate R Func<R>();
  public delegate R Func<T1, R>(T1 arg1);
  public delegate R Func<T1, T2, R>(T1 arg1, T2 args);
  public delegate R Func<T1, T2, T3, R>(T1 arg1, T2 args, T3 arg3);
  public delegate R Func<T1, T2, T3, T4, R>(T1 arg1, T2 args, T3 arg3, T4 arg4);
  public delegate R Func<T1, T2, T3, T4, T5, R>(T1 arg1, T2 args, T3 arg3, T4 arg4, T5 arg5);
  public class Reflector
  {
  private object target;
  public object Target
  {
  get { return target; }
  }
  public T Property<T>(string name)
  {
  PropertyInfo pi = target.GetType().GetProperty(name, typeof(T));
  if (null != pi && pi.CanRead)
  {
  object value = pi.GetValue(target, null);
  if (null != value)
  {
  return (T)value;
  }
  }
  return default(T);
  }
  public T SetProperty<T>(string name, T value)
  {
  PropertyInfo pi = target.GetType().GetProperty(name, typeof(T));
  if (null != pi && pi.CanWrite)
  {
  pi.SetValue(target, value, null);
  }
  return value;
  }
  public Proc Proc(string name)
  {
  MethodInfo mi = target.GetType().GetMethod(name, Type.EmptyTypes);
  if (null != mi)
  {
  return Delegate.CreateDelegate(typeof(Proc), target, mi.Name, false) as Proc;
  }
  return null;
  }
  public Proc<T> Proc<T>(string name)
  {
  MethodInfo mi = target.GetType().GetMethod(name, new Type[] { typeof(T) });
  if (null != mi)
  {
  return Delegate.CreateDelegate(typeof(Proc<T>), target, mi.Name, false) as Proc<T>;
  }
  return null;
  }
  public Proc<T1, T2> Proc<T1, T2>(string name)
  {
  MethodInfo mi = target.GetType().GetMethod(name, new Type[] { typeof(T1), typeof(T2) });
  if (null != mi)
  {
  return Delegate.CreateDelegate(typeof(Proc<T1, T2>), target, mi.Name, false) as Proc<T1, T2>;
  }
  return null;
  }
  public Proc<T1, T2, T3> Proc<T1, T2, T3>(string name)
  {
  //...
  }
  public Proc<T1, T2, T3, T4> Proc<T1, T2, T3, T4>(string name)
  {
  //...
  }
  public Proc<T1, T2, T3, T4, T5> Proc<T1, T2, T3, T4, T5>(string name)
  {
  //...
  }
  public Func<R> Func<R>(string name)
  {
  MethodInfo mi = target.GetType().GetMethod(name, Type.EmptyTypes);
  if (null != mi)
  {
  return Delegate.CreateDelegate(typeof(Func<R>), target, mi.Name, false) as Func<R>;
  }
  return null;
  }
  public Func<T1, R> Func<T1, R>(string name)
  {
  MethodInfo mi = target.GetType().GetMethod(name, new Type[] { typeof(T1) });
  if (null != mi)
  {
  return Delegate.CreateDelegate(typeof(Func<T1, R>), target, mi.Name, false) as Func<T1, R>;
  }
  return null;
  }
  public Func<T1, T2, R> Func<T1, T2, R>(string name)
  {
  //...
  }
  }
  封装的实现并不复杂,只是利用了泛型和泛型委托为调用者提供了强类型的属性和方法;除属性和方法的名称是动态的以为,其余的都可以加上类型约束。欢迎就此话题多多交流!