主頁 > .NET開發 > 02.反射Reflection

02.反射Reflection

2021-08-06 06:01:49 .NET開發

1. 基本了解

1.1 反射概述

文字說明

審查元資料并收集關于它的型別資訊的能力稱為反射,其中元資料(編譯以后的最基本資料單元)就是一大堆的表,當編譯程式集或者模塊時,編譯器會創建一個類定義表,一個欄位定義表,和一個方法定義表等

反射提供了封裝程式集、模塊和型別的物件(Type 型別),可以使用反射動態創建型別的實體,將型別系結到現有物件,或從現有物件獲取型別并呼叫其方法或訪問其欄位和屬性,如果代碼中使用了屬性,可以利用反射對它們進行訪問

實際上

反射是微軟封裝的一個幫助類別庫:using System.Reflection;

1.2 反射用途

  • 使用Assembly定義和加載程式集,加載在程式集清單中列出模塊,以及從此程式集中查找型別并創建該型別的實體
  • 使用Module了解包含模塊的程式集以及模塊中的類等,還可以獲取在模塊上定義的所有全域方法或其他特定的非全域方法
  • 使用ConstructorInfo了解建構式的名稱、引數、訪問修飾符(如pulicprivate)和實作詳細資訊(如abstractvirtual)等;使用TypeGetConstructorsGetConstructor方法來呼叫特定的建構式
  • 使用MethodInfo了解方法的名稱、回傳型別、引數、訪問修飾符(如pulicprivate)和實作詳細資訊(如abstractvirtual)等;使用TypeGetMethodsGetMethod方法來呼叫特定的方法
  • 使用FiedInfo了解欄位的名稱、訪問修飾符(如publicprivate)和實作詳細資訊(如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 示例:加載程式集

方式一:Loadc2 參考了 Helper,有參考關系

using System;
using System.Reflection;
using Helper;

namespace c2
{
    class Program
    {
        static void Main(string[] args)
        {
            // 相對路徑下加載指定名稱程式集檔案
            Assembly assembly = Assembly.Load("Helper");
        }
    }
}

示例二:LoadFilec2taskdao無參考關系

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");
        }
    }
}

示例三:LoadFromc2taskdao無參考關系

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");
        }
    }
}

示例四:根據型別創建型別實體,c2taskdao無參考關系

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 = https://www.cnblogs.com/weiyongguang/p/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 = https://www.cnblogs.com/weiyongguang/p/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.LoadFileAssembly.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; }
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/291974.html

標籤:.NET Core

上一篇:總結開發中基于DevExpress的Winform界面效果

下一篇:02.反射Reflection

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more