淺談.NET反射的封裝_.Net教程
推薦:解析ASP.NET用戶(hù)控件說(shuō)明和添加事件在WEB開(kāi)發(fā)中經(jīng)常有一些代碼是在很多地方重復(fù)出現(xiàn)的,象導(dǎo)航欄、用戶(hù)登錄/注冊(cè)和首頁(yè)上面的一些固定欄目等。這些可重用的代碼我們可以把它寫(xiě)成一個(gè)通用模塊供需要的地方來(lái)引用,這樣做即節(jié)省了開(kāi)發(fā)時(shí)間還方便以后的維護(hù)。 在ASP.NET的web編程中提供了一種叫做
.NET反射提供了在運(yùn)行時(shí)獲取對(duì)象類(lèi)型元數(shù)據(jù)的途徑,使程序可以動(dòng)態(tài)地調(diào)用對(duì)象的屬性、方法。動(dòng)態(tài)性帶來(lái)的代價(jià)是反射調(diào)用不像基于靜態(tài)類(lèi)型的直接調(diào)用那樣簡(jiǎn)潔,且缺乏類(lèi)型檢查機(jī)制,失去了IDE智能提示,容易出錯(cuò);于是,不少朋友嘗試對(duì).NET反射進(jìn)行封裝。這個(gè)話(huà)題是仁者見(jiàn)仁,智者見(jiàn)智,這里我也談?wù)勛约簩?duì).NET反射封裝的思路,請(qǐng)先看下面的示例代碼:
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);
//獲取過(guò)程
Proc<string> sayHello = reflector.Proc<string>("SayHello");
sayHello("Ling");
//獲取函數(shù)
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;
}
}
相信您已經(jīng)從代碼看出了封裝的思路:利用泛型和泛型委托為動(dòng)態(tài)的反射添加靜態(tài)的類(lèi)型約束。下面我們就來(lái)簡(jiǎn)單看一下Reflector實(shí)現(xiàn)的關(guān)鍵部分:
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)
{
//...
}
}
封裝的實(shí)現(xiàn)并不復(fù)雜,只是利用了泛型和泛型委托為調(diào)用者提供了強(qiáng)類(lèi)型的屬性和方法;除屬性和方法的名稱(chēng)是動(dòng)態(tài)的以為,其余的都可以加上類(lèi)型約束。歡迎就此話(huà)題多多交流!
分享:淺析C#編程實(shí)現(xiàn)動(dòng)態(tài)生成Word文檔如何用C#編程實(shí)現(xiàn)動(dòng)態(tài)生成Word文檔并填充數(shù)據(jù)的效果呢?要使用C#操作word,首先要添加引用: 1、添加引用-COM-Microsoft Word 11.0 Object Library 2、在.cs文件中添加 using Word; 下面的例子中包括C#對(duì)Word文檔的創(chuàng)建、插入表格、設(shè)置樣式等操作: (例子
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實(shí)例(可帶附件)
- js實(shí)現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實(shí)現(xiàn)
- Asp.Net 無(wú)刷新文件上傳并顯示進(jìn)度條的實(shí)現(xiàn)方法及思路
- Asp.net獲取客戶(hù)端IP常見(jiàn)代碼存在的偽造IP問(wèn)題探討
- VS2010 水晶報(bào)表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(kù)(連接字符串的配置及獲取)
- asp.net頁(yè)面?zhèn)髦禍y(cè)試實(shí)例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲(chǔ)過(guò)程實(shí)現(xiàn)分頁(yè)示例代碼
.Net教程Rss訂閱編程教程搜索
.Net教程推薦
- C#中遍歷各類(lèi)數(shù)據(jù)集合的方法總結(jié)
- 用事實(shí)說(shuō)話(huà)!AJAX應(yīng)用程序開(kāi)發(fā)七宗罪
- C#中連接兩個(gè)DataTable,相當(dāng)于Sql的InnerJoin
- 關(guān)于URL的傳遞字符串問(wèn)題的研究
- 怎樣使ASP.NET實(shí)現(xiàn)頁(yè)面?zhèn)髦?/a>
- ASPX頁(yè)面出現(xiàn)亂碼的解決辦法
- C# WinForm判斷程序是否以管理員身份運(yùn)行
- 將文件上傳、下載(以二進(jìn)制流保存到數(shù)據(jù)庫(kù))實(shí)現(xiàn)代碼
- 編程技巧 用Asp.net動(dòng)態(tài)生成html頁(yè)面
- 基于.NET中建構(gòu)子中傳遞子對(duì)象的對(duì)象詳解
- 相關(guān)鏈接:
- 教程說(shuō)明:
.Net教程-淺談.NET反射的封裝
。