日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

C#反射教程(4)--Asp.Net/C#/WCF--編程設計網(wǎng)

 阿木_mv 2011-02-14
面試例題8:如何動態(tài)加載外部程序集并用反射獲取指定類型的信息?

考點:學習動態(tài)加載外部程序集的基本方法,理解Assembly類的Load()方法和LoadFrom()方法的區(qū)別。

出現(xiàn)頻率:★★★

解答

  通過System.Reflection命名空間下的Assembly類可以動態(tài)加載外部程序集,可選方法為Load()方法和 LoadFrom()方法。Load()方法用于加載當前程序集位于相同目錄下的外部程序集,LoadFrom()方法可以加載其他目錄中的程序集。以上示例中的ClassRef.exe程序作為需要加載的外部程序集,進一步獲取其指定類型的信息。在目錄下新建一個程序文件,并命名為 AppClassRef.cs,編寫代碼如代碼7.8所示。

代碼7.8 動態(tài)加載外部程序集:

+展開
-C#
using System;
//導入相應的命名空間
using System.Reflection;
using System.IO;

class AppClassRef
{
static void Main(string[] args)
{
//查看當前應用程序域的所有程序集
DisAllAm();
while (true)
{
Console.Write("請輸入所檢測的類型名稱:");
//接收用戶輸入值并賦值給input變量
string input = Console.ReadLine();
//如果用戶輸入"quit",則跳出循環(huán)
if (input == "quit")
{
break;
}
//聲明Assembly類型對象am
Assembly am;
try
{
//調(diào)用Assembly類的Load方法,將引用傳遞給am
am = Assembly.Load("ClassRef");
//以下代碼調(diào)用Assembly類的LoadFrom方法
//am = Assembly.LoadFrom(@"D:\web\NET\ClassRef.exe");
//調(diào)用am的GetType方法,并將Type對象引用返回給tp變量
Type tp = am.GetType(input, falsefalse);
//調(diào)用ClassB的Ref靜態(tài)方法,并傳遞tp對象
ClassB.Ref(tp);
}
//捕獲文件未找到異常
catch (FileNotFoundException e)
{
//輸出異常信息
Console.WriteLine("異常信息:{0}", e.Message);
}
//捕獲空對象引用異常
catch (NullReferenceException e)
{
//輸出異常信息
Console.WriteLine("異常信息:{0}", e.Message);
}
//捕獲一般異常
catch (Exception e)
{
//輸出異常信息
Console.WriteLine("異常信息:{0}", e.Message);
}
finally
{
//再次查看當前應用程序域的所有程序集
DisAllAm();
}
}
}
//定義DisAllAm方法,用于顯示程序集列表
static void DisAllAm()
{
Console.WriteLine("\n\t=============當前應用程序域中所有加載的程序集=============");
//通過GetAssemblies方法獲取當前應用程序域的所有程序集
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
{
//輸出程序集的名稱
Console.WriteLine("程序集:{0}", a.FullName);
}
}
}
class ClassB
{
//定義靜態(tài)方法Ref,接收一個Type類型的參數(shù)
public static void Ref(Type tp)
{
//輸出Type對象的基本屬性
string FullName = tp.FullName.ToString();
Console.WriteLine("\n\t============={0}類型的信息=============", FullName);
//獲取Type對象的所有公共成員并保存到mi數(shù)組
MemberInfo[] mi = tp.GetMembers();
//遍歷并輸出mi數(shù)組所有的子項屬性
foreach (MemberInfo m in mi)
{
Console.WriteLine("\t成員類別->{0},名稱->{1}",m.MemberType, m.Name);
}
//獲取Type對象所實現(xiàn)的接口并保存到Itp數(shù)組
Type[] Itp = tp.GetInterfaces();
//判斷Itp數(shù)組是否有子項,如果有則輸出子項屬性
if (Itp.Length != 0)
{
foreach (Type t in Itp)
{
Console.WriteLine("{0}實現(xiàn)的接口類型->{1}", FullName, t.FullName);
}
}
else
{
Console.WriteLine("{0}不實現(xiàn)的任何接口類型", FullName);
}
}
}

  本題的類型信息輸出和ClassRef.exe相同,這里不作過多講述。主程序中首先調(diào)用了DisAllAm()靜態(tài)方法,該方法封裝了列舉當前應用程序域所含程序集列表的代碼。在命令行下編譯AppClassRef.cs執(zhí)行AppClassRef程序,運行結(jié)果如圖7.13所示。

  本程序首先輸出了當前應用程序域所包含程序集的列表,可知當前僅有mscorlib程序集和AppClassRef程序集被加載。繼續(xù)操作,再次調(diào)用DisAllAm()方法,所輸出的程序集列表中已經(jīng)加入了ClassRef程序集。

                                                                                                                                 圖7.13 動態(tài)加載外部程序集

注意:mscorlib程序集包含了.NET大部分的基類庫,CLR運行時自動加載。

解析

  程序動態(tài)加載外部程序集,通過System.Reflection命名空間下的Assembly類實現(xiàn),該類的Load()方法和 LoadFrom()方法可以在運行時加載指定的外部程序集。加載外部程序集后,Assembly類將創(chuàng)建相應的對象,調(diào)用該對象的GetType()方法可獲取指定類型的詳細信息。假設加載D:\根目錄下的MyApp.exe程序集,并且定義Assembly類的對象am,其如以下代碼所示:

  序直接輸出了ClassA類的細節(jié)信息。再次輸入"ClassB",程序輸出ClassB類的細節(jié)信息,運行結(jié)果如圖7.10所示。

+展開
-C#
using System;
//導入相應的命名空間
using System.Reflection;
using System.IO;

Assembly am;
try
{
am = Assembly.Load("MyApp");
Type tp = am.GetType("指定類型名稱",false,false);
}
catch (FileNotFoundException e)
{
Console.WriteLine("異常信息:{0}", e.Message);
}

  以上代碼調(diào)用了Assembly類的Load()方法載入MyApp程序集(exe或dll),代碼正常加載的前提是當前程序集和MyApp程序集位于相同目錄。所以,Assembly類的LoadFrom()方法也比較常用,其編寫方法如下所示:

+展開
-C#
am = Assembly.LoadFrom("D:\MyApp.exe");

  可見,Assembly類的LoadFrom()方法需要傳遞外部程序集的完整路徑。當外部程序集加載后,可以通過訪問當前應用程序域的所含程序集,以確定加載是否成功。需要注意System.IO命名空間的導入,因為主程序中需要捕捉"文件未找到"的異常,防止外部程序集不存在。

  說明:讀取AppDomain類的CurrentDomain屬性,可返回當前應用程序域,調(diào)用當前應用程序域的GetAssemblies方法,可獲取所包含程序集的集合。

面試例題9:如何通過晚期綁定調(diào)用方法成員?

考點:晚期綁定的含義,晚期綁定的基本方法。

出現(xiàn)頻率:★★★

解答

  晚期綁定即在編譯時不能確定是否存在類型,在運行時創(chuàng)建該類型的實例,調(diào)用其成員。本例程序分別定義了3個外部類型,編譯為dll程序集,由 LateBinding.cs代碼動態(tài)加載,調(diào)用其內(nèi)部方法。在目錄下新建一個程序文件,并命名為OldClass.cs,編寫代碼如代碼7.9所示。

代碼7.9 第1個外部類:OldClass.cs

+展開
-C#
public class OldClass
{
//定義public權(quán)限的Method靜態(tài)方法
public static string Method(string s)
{
string output = "OldClass類的Method靜態(tài)方法返回結(jié)果:" + s;
return output;
}
}

在目錄下新建一個程序文件,并命名為NewClass.cs,編寫代碼如代碼7.10所示。

代碼7.10 第2個外部類:NewClass.cs

+展開
-C#
public class NewClass
{
//定義public權(quán)限的Method實例方法
public string Method(string s)
{
string output = "NewClass類的Method實例方法返回結(jié)果:" + s;
return output;
}
}

在目錄下新建一個程序文件,并命名為MyClass.cs,編寫代碼如代碼7.11所示。

代碼7.11 第3個外部類:MyClass.cs

+展開
-C#
public class MyClass
{    
//定義public權(quán)限的Method實例方法
public string Method(string s)
{
string output = "MyClass類的Method實例方法返回結(jié)果:" + s;
return output;
}
//定義public權(quán)限的MethodTxt實例方法
public string MethodTxt()
{
string output = "MyClass類的MethodTxt無參數(shù)實例方法被調(diào)用";
return output;
}
}

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多