C#反射機制

来源:https://www.cnblogs.com/qiantao/archive/2018/11/05/9908410.html
-Advertisement-
Play Games

在還不太熟悉反射的昨天 ,以為反射很神秘 ,在網上到處找答案 .今天找了段代碼敲了一下 ,茅塞頓開 ! 其實反射也就那麼簡單的一回事 ! 反射是一種機制 , 通過這種機制我們可以知道一個未知類型的類型信息 .比如 ,有一個對象 a, 這個 對象不是我們定義的,也許是通過網路捕捉到的,也許是使用泛型定 ...


在還不太熟悉反射的昨天 ,以為反射很神秘 ,在網上到處找答案 .今天找了段代碼敲了一下 ,茅塞頓開 !

其實反射也就那麼簡單的一回事 !

反射是一種機制 , 通過這種機制我們可以知道一個未知類型的類型信息 .比如 ,有一個對象 a, 這個

對象不是我們定義的,也許是通過網路捕捉到的,也許是使用泛型定義的,但我們想知道這個對象的

類型信息,想知道這個對象有哪些方法或者屬性什麼的.甚至我們想進一步調用這個對象的方法.關

鍵是現在我們只知道它是一個對象,不知道它的類型,自然不會知道它有哪些方法等信息.這時我們

該怎麼辦?反射機制就是解決這麼一個問題的. 通過反射機制我們可以知道未知類型對象的類型信息.

再比如,我們有一個 dll 文件,我們想調用裡面的類.現在假設這個 dll 文件的類的定義,數量

等不是固定的,是經常變化的.也許某一天你要在這個 dll 裡面增加一個類定義.也許你覺得這沒什

麽問題,現在關鍵是我們在另一個程式集裡面要調用這個 dll ,這是我們的程式必須能夠適應這個 dll

的變化,也就是說即使改變了 dll 文件的定義也不需要改變我們的程式集.這時候我們就會使用一個

未知 dll .我們該怎麼辦?同樣,反射機制幫助了我們,我們可以通過反射來實現.

說白了,反射就是能知道我們未知類型的類型信息這麼一個東西.沒什麼神秘可講!

今天我先講一個獲得程式集信息的例子.

下麵我們來舉一個例子. 例子的思路是這樣的: 我們有一個 dll. dll 裡面有許多關於運動的類. 每

一個類記錄了一種體育運動的信息.我們在另外一個程式裡面要知道這個 dll 的信息:(如果你還不

能明白我的意思,請耐心的照我的步驟把這個過程走一變!)

第一步:我們建一個文件 Sport.cs. 內容如下:

using System;
public abstract class Sport
{
    protected string name;
    public abstract string GetDuration();
    public abstract string GetName();
}

咱們用命令" csc /t:library Sport.cs "編譯它.

第二步,我們再建一個名為 SomeSports.cs 的文件,內容如下:

using System;
public class Football : Sport
{
    public Football()
    {
        name = "Football";
    }
    public override string GetDuration()
    {
        return "four 15 minute quarters";
    }
    public override string GetName()
    {
        return name;
    }
}
public class Hockey : Sport
{
    public Hockey()
    {
        name = "Hockey";
    }
    public override string GetDuration()
    {
        return "three 20 minute periods";
    }
    public override string GetName()
    {
        return name;
    }
}
public class Soccer : Sport
{
    public Soccer()
    {
        name = "Soccer";
    }
    public override string GetDuration()
    {
        return "two 45 minute halves";
    }
    public override string GetName()
    {
        return name;
    }
}

下麵我們用命令" csc /t:library /r:Sport.dll SomeSports.cs "編譯該文件.

現在我們有了我們的運動信息 dll 文件.現在我們想通過程式知道裡面有哪些類.請進入最後一

步:

第三步:我們創建文件 AssemblyDemo cs.內容如下:

using System;
using System.Reflection;
public class AssemblyDemo
{
    public static void Main(string[] args)
    {
        int i, j;
        //==========================
        //First the command line arguments are evaluated.if there isn't
        //at least one,a usage message is printed
        //=================================
        if (args.GetLength(0) < 1)
        {
            Console.WriteLine("usage is AssemblyDemo<library_name>");
        }
        else
        {
            //========================
            // An Assembly object is obtained from the command line argument
            //========================
            Assembly assembly = Assembly.LoadFrom(args[0]);
            Type[] types = assembly.GetTypes();
            Console.WriteLine(assembly.GetName().Name + "contains the following types");
            for (i = 0; i < types.GetLength(0); ++i)
            {
                Console.WriteLine("\r(" + i + ") " + types[i].Name);
            }
            i = types.Length - 1;
            Console.Write("make selection(0-" + i + ");");
            j = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine();
            if (types[j].IsSubclassOf(typeof(Sport)))
            {
                ConstructorInfo ci = types[j].GetConstructor(new Type[0]);
                Sport sport = (Sport)ci.Invoke(new Object[0]);
                Console.WriteLine(sport.GetName() + "has" + sport.GetDuration());
            }
            else
            {
                Console.WriteLine(types[j].Name + "is not a sub-class of Sport");
            }
        }
    }
}

咱們用命令" csc /r:Sport.dll AssemblyDemo.cs "編譯該文件.

下麵我們用"A ssemblyDemo SomeSports.dll "運行該程式.

進一步程式要求我們輸入選項, 咱們輸入1,就顯示了結果: ockeyhasthree 20 minute periods.

好了,今天就到這裡了,下麵我將進一步說明如何用反射機制訪問對象的類型信息

我不想在這裡過多的描述反射的概念。我還是用我自己覺得最簡單、最直接的語言來描述反射

——“反射就是一種機制,通過這種機制,我們能知道一些位知程式集的詳細信息!”;通過上一篇

我們已經學會如何得到一個未知程式集的相關信息, 接下來我要講的是如何知道未知程式模塊的信息:

模塊信息是通過 Module 類訪問的。下麵通過一個類子,講解下 Module 類的使用,如果你是

一個用心的程式員,應該瞭解下 Module 的詳細信息。

下麵我們寫一個新的文件 ModuleDemo.cs 。內容如下:

// 編譯命令 csc /r:Sport.dll ModuleDemo.cs

using System;
using System.Reflection;
public class ModuleDemo
{
    public static void Main(string[] args)
    {
        //=======================
        // Am Module object is obtained representing the
        // SomeSports.dll library file
        //=======================
        Assembly assembly = Assembly.Load("SomeSports");
        Module module = assembly.GetModule("SomeSports.dll");
        //======================
        //Search the module for the type named "Football"
        Type[] types = module.FindTypes(Module.FilterTypeName, "Football");
        if (types.Length != 0)
        {
            ConstructorInfo ci = types[0].GetConstructor(new Type[0]);
            Sport sport = (Sport)ci.Invoke(new Object[0]);
            Console.WriteLine(sport.GetName() + " has " + sport.GetDuration());
        }
        else
        {
            Console.WriteLine("type not found");
        }
    }
}

我們用 csc /r:Sport.dll ModuleDemo.cs 編譯,然後用 MouduleDemo 運行程式就能看到如下輸

:Football has four 15 minute quarters

關於 C# 反射的基礎知識,還有一個知識點就是訪問未知對象的類型信息。

註:內容來源於網路

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程池對於性能優化無處不在 1.樓主在平時產品開發過程中所遇到的性能問題,特別是最近特別流行的微服務架構、 web - java - 底層數據源(python亦或者opensatck),對於這種前後臺分離的場景 無時無刻會存在對於業務場景需要對同一數據源進行百次,千次的重覆調用過程、 性能方面就會出 ...
  • Lua表類似HashMap Lua的表本質其實是個類似HashMap的東西,其元素是很多的Key Value對,如果嘗試訪問了一個表中並不存在的元素時,就會觸發Lua的一套查找機制,也是憑藉這個機制來模擬了類似“繼承”的行為 舉例說明: 輸出為nil的原因很簡單,tempTable中並沒有membe ...
  • 1.迭代器的遍歷原理,首先,我們先來聊一下迭代器的迭代原理,這裡以集合為例。通常迭代器在集合中可以作為遍歷集合中元素的一種方式,如下代碼,通過集合的list.Iterator()方法得到迭代器,然後進入while迴圈,執行it.hasNext()語句判斷集合中下一個對象是否存在,存在進迴圈。執行it ...
  • 歡迎加入python學習交流群:646293950,一起交流學習,共同進步。 ...
  • 一.byte和int相互轉換的方法 java程式或Android程式的socket數據傳輸,都是通過byte數組,但是int類型是4個byte組成的,如何把一個整形int轉換成byte數組,同時如何把一個長度為4的byte數組轉換為int類型。 /** * int到byte[] * @param i ...
  • 繼國慶節 SmartCode 正式版(SmartCode.Generator)發佈之後,SmartCode 迎來了新的能力 SmartCode.ETL ! SmartCode 正式版從開始發佈就從未說過自己僅僅是個代碼生成器,這點上從我第一次宣佈SmartCode正式開源的文章就可以說明: "《Sm ...
  • 廢話不多說,直接上代碼 下麵寫個demo測試一下。 上面的案例是一個200塊錢的紅包分10份,列印結果如下 這種分紅包的方式有一個缺陷,就是 紅包的金額 <= 剩下的金額 / 剩下的次數 大家有沒有更好的分紅包方式呢 ...
  • 1. Node.cs 2.LinkList.cs 3.Program.cs 輸出結果: 5為鏈表的長度 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...