1. 基本了解
1.1 反射概述
文字說明
審查元數據並收集關於它的類型信息的能力稱為反射,其中元數據(編譯以后的最基本數據單元)就是一大堆的表,當編譯程序集或者模塊時,編譯器會創建一個類定義表,一個字段定義表,和一個方法定義表等
反射提供了封裝程序集、模塊和類型的對象(Type
類型),可以使用反射動態創建類型的實例,將類型綁定到現有對象,或從現有對象獲取類型並調用其方法或訪問其字段和屬性。如果代碼中使用了屬性,可以利用反射對它們進行訪問
實際上
反射是微軟封裝的一個幫助類庫:using System.Reflection;
1.2 反射用途
- 使用
Assembly
定義和加載程序集,加載在程序集清單中列出模塊,以及從此程序集中查找類型並創建該類型的實例 - 使用
Module
了解包含模塊的程序集以及模塊中的類等,還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法 - 使用
ConstructorInfo
了解構造函數的名稱、參數、訪問修飾符(如pulic
或private
)和實現詳細信息(如abstract
或virtual
)等;使用Type
的GetConstructors
或GetConstructor
方法來調用特定的構造函數 - 使用
MethodInfo
了解方法的名稱、返回類型、參數、訪問修飾符(如pulic
或private
)和實現詳細信息(如abstract
或virtual
)等;使用Type
的GetMethods
或GetMethod
方法來調用特定的方法 - 使用
FiedInfo
了解字段的名稱、訪問修飾符(如public
或private
)和實現詳細信息(如static
)等,並獲取或設置字段值。 - 使用
EventInfo
了解事件的名稱、事件處理程序數據類型、自定義屬性、聲明類型和反射類型等,添加或移除事件處理程序。 - 使用
PropertyInfo
了解屬性的名稱、數據類型、聲明類型、反射類型和只讀或可寫狀態等,獲取或設置屬性值 - 使用
ParameterInfo
了解參數的名稱、數據類型、是輸入參數還是輸出參數,以及參數在方法簽名中的位置等
1.3 反射常用類
反射是一個程序集發現及執行的過程,通過反射能夠得到 .exe
或.dll
等程序集內部的信息,使用反射能夠看到一個程序集內部的接口、類、方法、字段、屬性、特性等信息
類型 | 描述 |
---|---|
Assembly | 通過此類能夠載入操縱一個程序集,並獲取程序集內部信息 |
FieldInfo | 該類保存給定的字段信息 |
MethodInfo | 該類保存給定的方法信息 |
MemberInfo | 該類是一個基類,定義了EventInfo,FieldInfo,MethodInfo,PropertyInfo的多個公用行為 |
Module | 該類能夠使你能訪問多個程序集中的給定模塊 |
ParameterInfo | 該類保存給定的參數信息 |
PropertyInfo | 該類保存給定的屬性信息 |
2. Assembly 程序集對象
2.1 對象簡介
官方文檔
程序集包含模塊、模塊包含類型,而類型包含成員。 反射提供封裝程序集、模塊和類型的對象。 可以使用反射動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型
其它文檔
System.Reflection.Assembly
:表示一個程序集
程序集是代碼進行編譯是的一個邏輯單元,把相關的代碼和類型進行組合,然后生成PE文件(例如可執行文件.exe
和類庫文件.dll
)
由於程序集在編譯后並不一定會生成單個文件,而可能會生成多個物理文件,甚至可能會生成分布在不同位置的多個物理文件,所以程序集是一個邏輯單元,而不是一個物理單元;即程序集在邏輯上是一個編譯單元,但在物理儲存上可以有多種存在形式
對於靜態程序集可以生成單個或多個文件,而動態程序集是存在於內存中的
在C#中程序集處處可見,因為任何基於.NET的代碼在編譯時都至少存在一個程序集(所有.NET項目都會默認引用mscorlib
程序集)
程序集包含了兩種文件:可執行文件(.exe
文件)和 類庫文件(.dll
文件)
在VS開發環境中,一個解決方案可以包含多個項目,而每個項目就是一個程序集
2.2 應用程序結構
包含應用程序域(AppDomain
),程序集(Assembly
),模塊(Module
),類型(Type
),成員(EventInfo、FieldInfo、MethodInfo、PropertyInfo
) 幾個層次
2.3 靜態方法
常用靜態方法
方法 | 返回值類型 | 描述 |
---|---|---|
Assembly.Load | Assembly | 加載相對路徑下指定名稱程序集 |
Assembly.LoadFile | Assembly | 根據全路徑獲取指定程序集 |
Assembly.LoadFrom | Assembly | 根據全路徑獲取指定程序集 |
2.4 實例方法,屬性
常用實例屬性
屬性 | 屬性值類型 | 描述 |
---|---|---|
assembly.FullName | string | 獲取程序集的顯示名稱 |
assembly.Location | string | 獲取程序集的完整路徑(全名稱) |
assembly.DefinedTypes | IEnumerable
|
獲取定義在程序集中類型集合 |
assembly.Modules | IEnumerable
|
獲取定義在程序集中模塊集合 |
常用實例方法
方法 | 返回值 | 描述 |
---|---|---|
assembly.GetTypes() | Type[] | 獲取程序集中定義的類型數組 |
assembly.GetType() | Type | 獲取程序集中定義的類型 |
assembly.GetExportedTypes() | Type[] | 獲取程序集中定義的所有公共類型(類,接口,枚舉等) |
assembly.CreateInstance() | object | 根據傳入類型創建類型實例 |
2.5 示例:加載程序集
方式一:
Load
,c2
引用了Helper
,有引用關系
using System;
using System.Reflection;
using Helper;
namespace c2
{
class Program
{
static void Main(string[] args)
{
// 相對路徑下加載指定名稱程序集文件
Assembly assembly = Assembly.Load("Helper");
}
}
}
示例二:
LoadFile
,c2
與taskdao
無引用關系
using System;
using System.Reflection;
namespace c2
{
class Program
{
static void Main(string[] args)
{
// 根據全名稱(路徑+文件名.后綴)下加載指定名稱程序集文件
Assembly assembly =
Assembly.LoadFile(@"E:\SolutionZX\taskdao\bin\Debug\taskdao.dll");
}
}
}
示例三:
LoadFrom
,c2
與taskdao
無引用關系
using System;
using System.Reflection;
namespace c2
{
class Program
{
static void Main(string[] args)
{
// 根據全名稱(路徑+文件名.后綴)下加載指定名稱程序集文件
Assembly assembly =
Assembly.LoadFrom(@"E:\SolutionZX\taskdao\bin\Debug\taskdao.dll");
}
}
}
示例四:根據類型創建類型實例,
c2
與taskdao
無引用關系
dynamic
類型為動態類型,使用時編譯器不會檢查(運行時檢查)
using System;
using System.Reflection;
namespace c2
{
class Program
{
static void Main(string[] args)
{
// 根據全名稱(路徑+文件名.后綴)下加載指定名稱程序集文件
Assembly assembly =
Assembly.LoadFrom(@"E:\SolutionZX\taskdao\bin\Debug\taskdao.dll");
// object _t = assembly.CreateInstance("task1dao.task1");
// 報錯,object類型識別不出Show方法,因為C#是強類型語言
// _t.Show();
dynamic _t = assembly.CreateInstance("task1dao.task1");
_t.Show();
}
}
}
2.6 獲取類型
獲取普通類型
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo");
獲取泛型類型
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo`1"); // UserInfo`1 英文狀態下數字1左邊符號,參數個數
3. Type 類型
在C#中可以理解為一個類對應一個Type
對象
3.1 實例屬性,方法
實例屬性
屬性 | 屬性值類型 | 描述 |
---|---|---|
type.Name | string | 獲取類型名稱(類名) |
type.FullName | string | 獲取類全名(命名空間+類名稱) |
type.Namespace | string | 獲取類所在的命名空間 |
type.Assembly | string | 獲取類所在程序集名稱 |
type.BaseType | Type | 獲取基類(父類) |
type.IsSubclassOf(Type parent) | bool | type是否是parent的子類 |
type.IsInstanceOfType(object o) | bool | o是否是type類的對象 |
type.IsClass | bool | 獲取對象類型是否是類 |
type.IsInterface | bool | 獲取對象類型是否是接口 |
type.IsNotPublic | bool | 獲取對象類型是否公開 |
type.IsAbstract | bool | 獲取對象類型是否是抽象的 |
type.IsSealed | bool | 獲取對象類型是否是密封的 |
type.IsArray | bool | 獲取對象類型是否是數組 |
type.IsEnum | bool | 獲取對象類型是否是枚舉 |
實例方法
方法 | 返回值類型 | 描述 |
---|---|---|
type.GetMembers() | MemberInfo[] | 獲取類型中所有公共成員 |
type.GetMethods() | MethodInfo[] | 獲取所有公共方法(包含基類) |
type.GetConstructors() | ConstructorInfo[] | 獲取類型中所有公共構造函數 |
type.GetFields() | FieldInfo[] | 獲取所有公共字段 |
type.GetProperties() | PropertyInfo[] | 獲取所有公共屬性 |
type.GetInterfaces() | Type[] | 獲取所有公共接口 |
type.GetCustomAttributes(...) | object[] | 獲取此類型指定特性數組 |
type.MakeGenericType(...) | Type | 設置泛型類,泛型參數類型 |
type.GetMember(...) | MemberInfo[] | 多個,獲取公共成員(不常用) |
type.GetMethod(...) | MethodInfo | 單個,獲取公共方法 |
type.GetConstructor(...) | ConstructorInfo | 單個,獲取公共方法 |
type.GetField(...) | FieldInfo | 單個,獲取公共字段 |
type.GetProperty(...) | PropertyInfo | 單個,獲取公共屬性 |
type.GetInterface(...) | Type | 單個,獲取公共接口 |
type.IsDefined(...) | bool | 獲取此類型是否繼承指定特性 |
type.GetCustomAttribute(...) | Attribute | 單個,獲取此類型指定特性 |
3.2 操作示例一
public class Base
{
}
public interface Inta { }
public interface Intb { }
public class UserInfo<A> : Base, Inta, Intb
{
#region 公共構造函數
public UserInfo()
{
Console.WriteLine("無參構造方法...");
}
public UserInfo(int id)
{
Console.WriteLine("1個參數構造方法");
}
#endregion
#region 私有構造函數
private UserInfo(string name) { }
#endregion
#region 公共字段
public string code;
#endregion
#region 私有字段
private string msg;
#endregion
#region 公共屬性
public int id { get; set; }
#endregion
#region 公共方法
public void Print()
{
Console.WriteLine("無參數實例方法");
}
public void Show()
{
Console.WriteLine("無參數重載實例方法");
}
public void Show(int id)
{
Console.WriteLine("有參數重載實例方法-" + id.ToString());
}
#endregion
#region 公共靜態方法
public static void Statc() { }
#endregion
#region 私有方法
private void GetM()
{
Console.WriteLine("無參數私有方法");
}
private void GetM(int i)
{
Console.WriteLine("有參數私有方法-" + id.ToString());
}
#endregion
#region 公共泛型方法
public void GenericC(A a)
{
Console.WriteLine("公共泛型無參方法:" + a.ToString());
}
public void GenericS<T>()
{
Console.WriteLine("公共泛型無參方法");
}
public void GenericsA<T>(A a, T t)
{
Console.WriteLine("公共泛型有參方法:" + t.ToString() + "\t" + a.ToString());
}
#endregion
}
通過類獲得對應的
Type
Type type = typeof(UserInfo);
通過
Assembly
對象,通過類的fullname
類獲得Type
對象
Assembly assem = Assembly.LoadFrom(@"E:\SolutionRP\DMO\bin\Debug\DMO.dll");
Type type = assem.GetType("DMO.UserInfo");
綜合示例
Type type = typeof(UserInfo);
Console.WriteLine("類型名:" + type.Name);
Console.WriteLine("類全名:" + type.FullName);
Console.WriteLine("命名空間名:" + type.Namespace);
Console.WriteLine("程序集名:" + type.Assembly);
Console.WriteLine("模塊名:" + type.Module);
Console.WriteLine("基類名:" + type.BaseType);
Console.WriteLine("是否類:" + type.IsClass);
MethodInfo method = type.GetMethod("Show");//獲得實例的方法
Console.WriteLine("類的公共成員:");
MemberInfo[] memberInfos = type.GetMembers();//得到所有公共成員
foreach (var item in memberInfos)
{
Console.WriteLine("成員類型:" + item.MemberType + "\t成員:" + item);
}
3.3 示例二:獲取公共方法
一:獲取所有公共成員
static void Main(string[] args)
{
Type type = typeof(UserInfo);
Console.Write("獲取所有公共成員:");
MemberInfo[] members = type.GetMembers();
Console.WriteLine(members.Length);
Console.Write("獲取所有公共方法(包含基類):");
MethodInfo[] methods = type.GetMethods();
Console.WriteLine(methods.Length);
Console.Write("獲取所有公共構造函數:");
ConstructorInfo[] constructors = type.GetConstructors();
Console.WriteLine(constructors.Length);
Console.Write("獲取所有公共字段:");
FieldInfo[] fields = type.GetFields();
Console.WriteLine(fields.Length);
Console.Write("獲取所有公共屬性:");
PropertyInfo[] properties = type.GetProperties();
Console.WriteLine(properties.Length);
Console.Write("獲取所有公共接口:");
Type[] interfaces = type.GetInterfaces();
Console.WriteLine(interfaces.Length);
}
根據名稱獲取公共成員(不常用)
MemberInfo[] memberInfo1 = type.GetMember("code");
MemberInfo[] memberInfo2 = type.GetMember("Show");
Console.WriteLine(memberInfo1.Length);
Console.WriteLine(memberInfo2.Length);
根據名稱獲取公共方法
// 獲取公共方法(非重載方法)
MethodInfo methodInfo1 = type.GetMethod("Print");
Console.WriteLine(methodInfo1.Name);
// 獲取公共重載方法,根據參數順序,類型,個數獲取
// 1.調用有一個int類型參數的重載方法
MethodInfo methodInfo2 = type.GetMethod("Show", new Type[] { typeof(int) });
// 2.調用無參數重載方法(不可傳null)
MethodInfo methodInfo3 = type.GetMethod("Show", new Type[0]);
Console.WriteLine(methodInfo3.Name);
根據參數的類型,數量,順序返回指定構造方法
// 返回無參公共構造方法
ConstructorInfo constructor1 = type.GetConstructor(new Type[0]);
// 返回有一個int類型參數的公共構造方法
ConstructorInfo constructor2 = type.GetConstructor(new Type[] { typeof(int) });
獲取類型公共字段
FieldInfo fieldInfo1 = type.GetField("code");
Console.WriteLine(fieldInfo1.Name);
獲取類型公共屬性
PropertyInfo propertyInfo1 = type.GetProperty("id");
Console.WriteLine(propertyInfo1.Name);
3.4 示例三:獲取靜態方法
3.5 示例四:獲取泛型方法
獲取泛型方法
Assembly assembly = typeof(Program).Assembly;
// 獲取有一個泛型參數的類
Type type = assembly.GetType("c2.UserInfo`1");
// 指定泛型參數類型
Type generictype = type.MakeGenericType(new Type[] { typeof(int) });
object oType = Activator.CreateInstance(generictype);
3.6 示例五:獲取特性
[CustomAttribute]
public class Studen
{
public void Show()
{
}
}
public class CustomAttribute : Attribute
{
}
static void Main(string[] args)
{
Type type = typeof(Studen);
if(type.IsDefined(typeof(CustomAttribute), true))
{
// 如果有多個相同特性,默認取首個
Attribute attribute = type.GetCustomAttribute(typeof(CustomAttribute), true);
object[] oAttrbute = type.GetCustomAttributes(typeof(CustomAttribute), true);
Console.WriteLine(oAttrbute.Length);
}
}
4. MethodInfo 方法
一個 MethodInfo
表示一個方法(公共,私有,靜態,構造)
4.1 實例屬性,方法
實例屬性
屬性 | 屬性值類型 | 描述 |
---|---|---|
methodInfo.Name | string | 方法名稱 |
methodInfo.ReturnType | Type | 獲取方法返回值類型 |
methodInfo.IsConstructor | bool | 是否是構造方法 |
methodInfo.IsAbstract | bool | 是否為抽象方法 |
methodInfo.IsPrivate | bool | 是否為私有方法 |
methodInfo.IsPublic | bool | 是否為公共方法 |
methodInfo.IsStatic | bool | 是否為靜態方法 |
methodInfo.IsVirtual | bool | 是否為虛方法 |
methodInfo.IsGenericMethod | bool | 是否為泛型方法 |
實例方法
方法 | 返回值 | 描述 |
---|---|---|
methodInfo.Invoke(...) | object | 調用非泛型方法 |
methodInfo.GetParameters() | ParameterInfo[] | 獲取方法參數數組 |
methodInfo.IsDefined(...) | bool | 獲取此方法是否繼承指定特性 |
methodInfo.GetCustomAttribute(...) | Attribute | 單個,獲取指定特性 |
methodInfo.GetCustomAttributes(...) | object[] | 獲取此方法指定特性數組 |
4.2 操作示例一
獲取調用非泛型非重載無參數方法,無參數方法第二個參數可傳
null
,但不推薦
Type type = typeof(UserInfo);
object oType = Activator.CreateInstance(type);
MethodInfo methodInfo = null;
methodInfo = type.GetMethod("Print");
methodInfo.Invoke(oType,new object[0]);
methodInfo.Invoke(oType, null);
獲取調用非泛型重載無參數方法,無參數方法第二個參數可傳
null
,但不推薦
Type type = typeof(UserInfo);
object oType = Activator.CreateInstance(type);
MethodInfo methodInfo = null;
methodInfo = type.GetMethod("Show",new Type[0]);
methodInfo.Invoke(oType,new object[0]);
methodInfo.Invoke(oType, null);
獲取調用非泛型重載有參數方法,多個參數用逗號隔開,參數類型,個數,順序必須相同
Type type = typeof(UserInfo);
object oType = Activator.CreateInstance(type);
MethodInfo methodInfo = null;
methodInfo = type.GetMethod("Show", new Type[] { typeof(int) });
methodInfo.Invoke(oType, new object[] { 1 });
4.3 操作示例二
獲取泛型方法與獲取普通方法一致,泛型參數按從左到右順序傳入,方法參數類型與泛型參數類型一致
調用公共泛型無參方法
// 獲取泛型方法
MethodInfo methodInfo = type.GetMethod("GenericS");
// 指定泛型方法參數
MethodInfo genericmethod = methodInfo.MakeGenericMethod(new Type[] { typeof(int) });
genericmethod.Invoke(oType, null);
調用公共泛型有參方法
MethodInfo methodInfo = type.GetMethod("GenericsA");
MethodInfo genericsmethod =
methodInfo.MakeGenericMethod(new Type[] { typeof(int), typeof(string) });
genericsmethod.Invoke(oType, new object[] { 1 });
調用公共泛型類的有參方法,泛型類中的泛型參數與泛型方法的泛型參數一致
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo`1");
Type generictype = type.MakeGenericType(new Type[] { typeof(int) });
object oType = Activator.CreateInstance(generictype);
MethodInfo methodInfo = generictype.GetMethod("GenericC");
methodInfo.Invoke(oType, new object[] { 1 });
}
調用公共泛型類的有參方法,泛型類中的泛型參數與泛型方法的泛型參數不一致
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo`1");
Type generictype = type.MakeGenericType(new Type[] { typeof(int) });
object oType = Activator.CreateInstance(generictype);
MethodInfo methodInfo = generictype.GetMethod("GenericsA");
MethodInfo genericsmethodinfo =
methodInfo.MakeGenericMethod(new Type[] { typeof(string) });
genericsmethodinfo.Invoke(oType, new object[] { 2, "af" });
}
5. ConstructorInfo 構造函數
5.1 實例屬性,方法
實例方法
方法 | 返回值類型 | 描述 |
---|---|---|
constructor.Invoke(...) | object | 執行構造函數 |
constructor.IsDefined(...) | bool | 獲取此構造函數是否繼承指定特性 |
constructor.GetCustomAttribute(...) | Attribute | 單個,獲取指定特性 |
constructor.GetCustomAttributes(...) | object[] | 獲取此構造函數指定特性數組 |
5.2 操作實例一
public class User
{
public User()
{
Console.WriteLine("無參構造函數");
}
public User(string n)
{
Console.WriteLine("有參構造函數:" + n);
}
}
調用構造函數
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.User");
object oType = Activator.CreateInstance(type);
ConstructorInfo constructor = type.GetConstructor(new Type[0]);
constructor.Invoke(oType, null);
ConstructorInfo constructor1 = type.GetConstructor(new Type[] { typeof(string) });
constructor1.Invoke(oType, new object[] { "liai" });
ParameterInfo[] parameters = constructor1.GetParameters();
Console.WriteLine(parameters.Length);
}
6. PropertyInfo 屬性
6.1 實例屬性,方法
實例屬性
屬性 | 屬性值類型 | 描述 |
---|---|---|
property.Name | string | 獲取屬性名稱 |
property.CanRead | bool | 獲取屬性是否可讀 |
property.CanWrite | bool | 獲取屬性是否可寫 |
property.PropertyType | Type | 獲取屬性類型 |
實例方法
方法 | 返回值類型 | 描述 |
---|---|---|
property.SetValue(...) | void | 設置對象屬性 |
property.GetValue(...) | object | 獲取對象屬性值 |
property.IsDefined(...) | bool | 獲取此屬性是否繼承指定特性 |
property.GetCustomAttribute(...) | Attribute | 單個,獲取指定特性 |
property.GetCustomAttributes(...) | object[] | 獲取此屬性指定特性數組 |
6.2 操作實例一
獲取公共屬性
// 獲取所有
PropertyInfo[] propertys = type.GetProperty();
// 獲取指定
PropertyInfo property = type.GetProperty("no");
獲取屬性,設置屬性值,獲取屬性值
class Program
{
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.Order");
object oType = Activator.CreateInstance(type);
PropertyInfo property = type.GetProperty("no");
property.SetValue(oType,1);
var value = property.GetValue(oType);
Console.WriteLine(value);
}
}
public class Order
{
public int no { get; set; }
}
7. FieldInfo 字段
7.1 實例屬性,方法
實例屬性
屬性名 | 屬性值類型 | 描述 |
---|---|---|
field.Name | string | 獲取字段名稱 |
field.Is... | bool | 獲取字段是否為... |
field.FieldType | Type | 獲取字段類型 |
實例方法
方法 | 返回值類型 | 描述 |
---|---|---|
field.IsDefined(...) | bool | 獲取此字段是否繼承指定特性 |
field.GetCustomAttribute(...) | Attribute | 單個,獲取指定特性 |
field.GetCustomAttributes(...) | object[] | 獲取此字段指定特性數組 |
7.2 操作實例一
獲取字段
class Program
{
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.Order");
object oType = Activator.CreateInstance(type);
FieldInfo field = type.GetField("name");
FieldInfo[] fields = type.GetFields();
}
}
public class Order
{
public string name;
}
獲取值,設置值
class Program
{
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.Order");
object oType = Activator.CreateInstance(type);
FieldInfo field = type.GetField("name");
field.SetValue(oType, "libai");
var value = field.GetValue(oType);
Console.WriteLine(value);
}
}
public class Order
{
public string name;
}
8. 擴展補充
8.1 加載程序集
獲得當前【應用程序域】中的所有程序集
Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
獲得當前對象所屬的類所在的程序集
Assembly assembly = this.GetType().Assembly;
Assembly.LoadFile
與Assembly.LoadFrom
的差別
LoadFile
方法用來載入和檢查具有同樣標識但位於不同路徑中的程序集,但不會載入程序的依賴項LoadFrom
不能用於載入標識同樣但路徑不同的程序集
創建實例對象
此方法的作用與 new
一個實例對象相同
Activator.CreateInstance(type)
8.2 Module 程序集模塊
Assembly assembly = Assembly.Load("mscorlib");//加載程序集
Module module = assembly.GetModule("CommonLanguageRuntimeLibrary");//得到指定模塊
Console.WriteLine("模塊名:" + module.Name);
Type[] types = module.FindTypes(Module.FilterTypeName, "Assembly*");
foreach (var item in types)
{
Console.WriteLine("類名:" + item.Name);//輸出類型名
}
Console.Read();
8.3 BindingFlags說明
枚舉值 | 描述 |
---|---|
BindingFlags.Instance | 對象實例 |
BindingFlags.Static | 靜態成員 |
BindingFlags.Public | 指可在搜索中包含公共成員 |
BindingFlags.NonPublic | 指可在搜索中包含非公共成員(即私有成員和受保護的成員) |
BindingFlags.FlattenHierarchy | 指可包含層次結構上的靜態成員 |
BindingFlags.IgnoreCase | 表示忽略 name 的大小寫 |
BindingFlags.DeclaredOnly | 僅搜索 Type 上聲明的成員,而不搜索被簡單繼承的成員 |
BindingFlags.CreateInstance | 表示調用構造函數。忽略 name。對其他調用標志無效 |
8.4 屬性應用:ORM
簡易實現
public Order Find(int id)
{
string sql = "select id,name,createTime from order where id = " +id;
Type type = typeof(Order);
object oOrder = Activator.CreateInstance(type);
using (SqlConnection connection = new SqlConnection("constr"))
{
SqlCommand cmd = new SqlCommand(sql,connection);
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
foreach (var prop in type.GetProperties())
{
prop.SetValue(oOrder,prop.Name);
}
}
}
return (Order)oOrder;
}
// DTD
public class Order
{
public int no { get; set; }
public string name { get; set; }
public DateTime createTime { get; set; }
}
泛型版本
public T Find<T>(int id) where T : BaseEntity
{
string sql = "select id,name,createTime from order where id = " + id;
Type type = typeof(T);
object oOrder = Activator.CreateInstance(type);
using (SqlConnection connection = new SqlConnection("constr"))
{
SqlCommand cmd = new SqlCommand(sql, connection);
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
foreach (var prop in type.GetProperties())
{
prop.SetValue(oOrder, prop.Name);
}
}
}
return (T)oOrder;
}
public class BaseEntity { }
public class Order:BaseEntity
{
public int no { get; set; }
public string name { get; set; }
public DateTime createTime { get; set; }
}