C# 映射(Reflection) - acaj2018 的部落格 - udn部落格
acaj2018 的部落格
作家:資訊小幫手
文章分類
    Top
    C# 映射(Reflection)
    2025/07/04 15:44:51
    瀏覽:67
    迴響:0
    推薦:0
    引用0

    在開發程式的過程中,常常會想要更加靈活的寫法,而這時映射(Reflection)可以大力的幫助到你, Reflection 允許我們的程式在執行時再去檢查和操作型別資訊,這對於如果你想要建立動態、可擴展的程式來說非常方便。接下來,我將介紹一些Reflection的基本用法並包含程式碼Code,以便幫助你更好的掌握這項技術。

    第一步,我們需要引入Reflection所需的命名空間:

    using System;

    using System.Reflection;

    接下來,建立一個MyClass

    class MyClass
    {
      public int MyProperty { get; set; }
      public void MyMethod()
      {
        // 輸出一段簡單的文字
       Console.WriteLine("Hello, World!");
      }
    }

    internal class Program
    {
      static void Main(string[] args)
      {
       // 獲取類別型別資訊
       Type type = typeof(MyClass);
       Console.WriteLine("Class Name: " + type.Name);
       // 列出所有屬性
       foreach (var property in type.GetProperties())
       {
        Console.WriteLine("Property: " + property.Name);
       }
       // 列出所有方法
       foreach (var method in type.GetMethods())
       {
        Console.WriteLine("Method: " + method.Name);
       }
       // 暫停
       Console.ReadLine();
      }
    }

    執行結果如下:

    動態建立類型並叫用其方法

    假設我們想要創建一個 MyClass 的實體,但不直接使用 new 關鍵字。可以使用 Activator.CreateInstance 方法:

    Type type = typeof(MyClass);

    // 動態建立 MyClass 的實體

    object instance = Activator.CreateInstance(type);

     

    // 使用 GetMethod 獲取名為 MyMethod 的方法

    MethodInfo methodInfo = type.GetMethod("MyMethod");

    // 使用 Invoke 方法來呼叫 MyMethod

    methodInfo.Invoke(instance, null);

     

    執行結果如下:

    在這段程式碼中,我們動態建立了 MyClass 的一個實體,並使用Reflection 呼叫了 MyMethod 方法。值得注意的是,如果MyClass擁有建構式,在Activator.CreateInstance時會一併呼叫其建構式。

     

    修改屬性

    Reflection也可以用來修改物件的屬性:

    PropertyInfo propertyInfo = type.GetProperty("MyProperty");

    propertyInfo.SetValue(instance, 42);

     

    int propertyValue = (int)propertyInfo.GetValue(instance);

    Console.WriteLine("Property Value: " + propertyValue);

     

    執行結果如下:

    透過這種方式,我們可以在不直接引用類別的情況下操作其屬性,這在動態程式設計時常常使用到。

     

    呼叫私有成員

    有些情況下,我們可能會需要呼叫私有類別的成員。雖然並不常這樣使用但 Reflection其實能做到這一點:

    class MyClass
    {
      //私有方法
      private void PrivateMethod()
      {
       Console.WriteLine("我是一個私有的方法。");
      }
    }

     

    // BindingFlags.NonPublic 表示搜尋私有(private)的成員

    // BindingFlags.Instance 表示搜尋實例成員(非靜態成員)

    MethodInfo privateMethod = type.GetMethod("PrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);

    privateMethod.Invoke(instance, null);

     

    執行結果如下:

    通過 BindingFlags,我們可以去指定私有方法。但必須特別注意,請減少使用這種做法,因為這麼做可能違反了物件導向程式設計的封裝原則,且也可能違背了當初程式開發人員所設計的邏輯。

     

    使用時的注意事項

    雖然Reflection很方便,但在使用時也要注意以下幾點:

    • 性能:Reflection可能會比直接呼叫來的慢,在一些需要頻繁使用的情境下,還是要考慮Reflection的必要性。
    • 安全性:通過Reflection訪問私有的屬性、方法可能會導致問題。
    • 可維護性:當過度使用Reflection時,有可能導致程式變得難以理解和維護。
    • 躲避編譯器檢查:在平時直接呼叫方法如果有錯,在編譯時就可以發現錯誤,但使用Reflection時,往往需要你在執行當下才可以發現錯誤。

    結論

    Reflection是 C# 提供的非常有用的工具,能夠使我們靈活的去撰寫程式碼,Reflection的各種動態地呼叫方法、建立物件等操作讓初次接觸的我完全沉迷於其中,但在使用時真的不得不謹慎,由於繞過了編譯時的型別檢查和安全檢查,除了確保程式的效能和安全性,還得考慮程式的可讀性與可維護性。希望這篇文章有幫助到你,謝謝

     

    參考資料:

    https://learn.microsoft.com/zh-tw/dotnet/csharp/advanced-topics/reflection-and-attributes/

    回應
    你可能會有興趣的文章:

    限會員,要發表迴響,請先登入