欢迎您访问我爱IT技术网,今天小编为你分享的编程技术是:【谈.NET反射的封装】,下面是详细的分享!
谈.NET反射的封装
.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)
{
//...
}
}
封装的实现并不复杂,只是利用了泛型和泛型委托为调用者提供了强类型的属性和方法;除属性和方法的名称是动态的以为,其余的都可以加上类型约束。欢迎就此话题多多交流!
以上所分享的是关于谈.NET反射的封装,下面是编辑为你推荐的有价值的用户互动:
相关问题:关于.NET的反射
答:比如说插件技术,做插件,比如说,我有个文本编辑器,里面原来有的功能是改变字体大小就没别的功能了,但这个文本编辑器实现了支持插件的技术,也就是说里面可以用反射实现. 我要再添加一个功能就是改变字体颜色.做一个插件,放到指定的文件夹下,编辑器... >>详细
相关问题:什么是反射?如何实现反射?
答:反射则提供了封装程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。通过反射命名空间中的类以及 System.Type,您可以获取有关已加... >>详细
相关问题:怎么自定义注解和反射实现json的封装和解析
答:js是弱类型,如果要封装你可以直接构造自己的类型 距离 var array;//创建数组 var zs; array[0]=eval("("+"{\"name\":\"zhangsan\",\"age\":20}"+")"); array[1]=eval("("+"{\"name\":\"lisi\",\"age\":30}"+")"); >>详细
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
