關於Assembly【C#】
l l 情境
你是 Adventure Works 公司的開發人員,當前你需要建立一個應用程式,以報告由該公司開發人員編寫的代碼。該應用程式將載入一個程式集並使用反射來產生要用於程式碼檢閱和文檔化的報告。要改進效能,需要將該應用程式建立為控制台應用程式。在本練習中,將使用 Assembly 類載入程式集,而程式集名稱和路徑應由使用者提供。
你希望建立一個對不同應用程式中編寫的代碼進行文檔化的應用程式。在本練習中,該應用程式將使用多個資訊類型反射類,以產生一個用於程式碼檢閱和文檔化的基於控制台的報告。該報告會列舉程式集的名稱、位置、版本和其他程式集層級中繼資料。該報告還會列舉程式集中的模組、類、成員、方法和屬性。
步驟1:顯示程式集資訊
1) 聲明一個接受程式集作為參數的名為GenerateReport 的方法。
2) 編寫代碼,以顯示程式集資訊。
根據程式集在全域組件快取中的位置,顯示程式集的名稱和位置以及程式集的狀態。
結果:已經顯示程式集資訊。
步驟2:顯示程式集中所有模組和類型
1) 使用 GetModules 方法建立一個包含程式集中模組的報告。
該代碼會為程式集中的每個模組調用DisplayModuleInfo方法。
2) 聲明一個接受Module 方法作為參數的名為 DisplayModuleInfo 的方法。
3) 通過使用 GetTypes 方法來顯示每個方法中包含的類型列表。
該代碼會為模組中的每個類型調用 DisplayTypeInfo 方法。
結果:已經顯示了該程式集包含的模組列表和每個模組包含的類型列表。
步驟3:顯示所有類型中的欄位、屬性和方法。
1) 聲明一個接受Type 作為參數的名為 DisplayTypeInfo 的方法。
2) 使用 GetFields 方法顯示所有類型中的欄位列表。
該列表應包含以下資訊:
l 欄位名
l 欄位類型
l 欄位是公用還是私人
3) 使用 GetProperties 方法顯示所有屬性列表。
該列表應包含以下資訊:
l 屬性名稱
l 屬性類型
l 屬性是可讀還是可寫
4) 顯示當前類型中所有方法的列表。
該代碼會為類型中的每個方法調用 DisplayMethodInfo 方法。
結果:已經顯示每種類型中的欄位列表、屬性列表以及方法列表。
步驟4:顯示所有方法中包含的資訊
1) 聲明一個接受 MethodInfo 作為參數的名為 DisplayMethodInfo 的方法。
2) 使用 GetParameters 方法顯示方法標頭檔資訊。
3) 使用 GetParameters 方法顯示所有參數的列表。
該列表應包含以下資訊:
l 參數名
l 參數類型
l 參數是否為 IsOptional、IsOut 或 IsRetval。
4) 使用 GetMethodBody 方法顯示關於每個方法的資訊。
該資訊應該包含方法中定義的堆棧大小和局部變數詳細資料,例如LocalIndex和LocalType。
5) 編譯並運行該應用程式。
主要代碼如下:
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Reflection;
5
6namespace crse3366ae_lab01
7{
8 class Program
9 {
10 static string ReadAssemblyFullPath()
11 {
12 string AssemblyPath, AssemblyName;
13 Console.Write("Type the assembly path: ");
14 AssemblyPath = Console.ReadLine();
15 Console.Write("Type the assembly name: ");
16 AssemblyName = Console.ReadLine();
17 return AssemblyPath + @"/" + AssemblyName;
18 }
19
20 static void Main(string[] args)
21 {
22 string AssemblyFullPath;
23 AssemblyFullPath = ReadAssemblyFullPath();
24 GenerateReport(AssemblyFullPath);
25 Console.Read();
26 }
27 static void GenerateReport(string path)
28 {
29 Assembly myAssemble = Assembly.LoadFile(path);
30 Console.WriteLine(myAssemble.FullName);
31 //myAssemble.
32 Console.WriteLine(string.Empty.PadLeft(45, '-'));
33 foreach (Type type in myAssemble.GetTypes())
34 {
35 Console.WriteLine("The name of Assemble is:"+type.Name);
36 Console.WriteLine("The path is:" + type.FullName);
37 }
38 GetModules(myAssemble);
39 }
40 static void GetModules(Assembly name)
41 {
42 Console.WriteLine(string.Empty.PadLeft(40, '-'));
43 foreach (Module module in name.GetModules())
44 {
45 Console.WriteLine("Module name:" + module.Name);
46 DisplayModuleInfo(module);
47 }
48 }
49 static void DisplayModuleInfo(Module module)
50 {
51 Console.WriteLine(string.Empty.PadLeft(35, '-'));
52 foreach (Type type in module.GetTypes())
53 {
54 Console.WriteLine("Module type name is:" + type.Name);
55 DisplayTypeInfo(type);
56 }
57 }
58 static void DisplayTypeInfo(Type type)
59 {
60 foreach (FieldInfo fieldInfo in type.GetFields())
61 {
62 Console.WriteLine("The name of this field is:" + fieldInfo.Name);
63 Console.WriteLine("The type of this field is:" + fieldInfo.GetType().ToString());
64 if (fieldInfo.IsPrivate)
65 {
66 Console.WriteLine("This field is Private!");
67 }
68 else
69 {
70 Console.WriteLine("This field is public");
71 }
72 }
73 Console.WriteLine(string.Empty.PadLeft(30, '-'));
74 foreach (PropertyInfo propertyInfo in type.GetProperties())
75 {
76 Console.WriteLine("The name of this property is:" + propertyInfo.Name);
77 Console.WriteLine("Type of this property is:" + propertyInfo.PropertyType.ToString());
78 if (propertyInfo.CanWrite)
79 {
80 Console.WriteLine("This property can write!");
81 }
82 else
83 {
84 Console.WriteLine("This property can't be write");
85 }
86 }
87 Console.WriteLine(string.Empty.PadLeft(30, '-'));
88 foreach (MethodInfo method in type.GetMethods())
89 {
90 Console.WriteLine("Method name:" + method.Name);
91 DisplayMethodInfo(method);
92 }
93 }
94 static void DisplayMethodInfo(MethodInfo method)
95 {
96 Console.WriteLine(string.Empty.PadLeft(25, '-'));
97 foreach (ParameterInfo parInfo in method.GetParameters())
98 {
99 Console.WriteLine("Parameter name is:"+parInfo.Name);
100 Console.WriteLine("Parameter type is:" + parInfo.ParameterType.ToString());
101 if (parInfo.IsOptional)
102 {
103 Console.WriteLine("This parameter is option!");
104 }
105 else
106 Console.WriteLine("This parrameter is not option!");
107 if (parInfo.IsOut)
108 {
109 Console.WriteLine("This parameter is out!");
110 }
111 else
112 Console.WriteLine("This parameter is not out!");
113 if (parInfo.IsRetval)
114 Console.WriteLine("and is retval");
115 else
116 Console.WriteLine("and is not retval");
117 }
118 if (method.GetMethodBody() != null)
119 {
120 GetMethodBody(method.GetMethodBody());
121 }
122 }
123 static void GetMethodBody(MethodBody body)
124 {
125 Console.WriteLine(string.Empty.PadLeft(20, '-'));
126 Console.WriteLine("Body Information :");
127 Console.WriteLine("Max stack size:" + body.MaxStackSize);
128 Console.WriteLine("Local variables are initialized:" + body.InitLocals);
129 Console.WriteLine(string.Empty.PadLeft(15, '-'));
130 foreach (LocalVariableInfo local in body.LocalVariables)
131 {
132 Console.WriteLine("Index of local var is:" + local.LocalIndex);
133 Console.WriteLine("Type of local var is:"+local.LocalType.ToString());
134 }
135 Console.WriteLine(string.Empty.PadLeft(20, '*'));
136 }
137 }
138}