2009-09-22 115 views

回答

31

Reflection的主要價值在於它可以用來檢查程序集,類型和成員。這是確定未知組件或對象內容的強大工具,可用於各種情況。

Reflection的反對者會指出它比較慢,與靜態代碼執行相比是真實的 - 但是在整個.NET框架中使用了Reflection,並且假設它沒有被濫用,它可以是一個非常強大的工具工具包。

一些有用的應用程序:

  • 確定的組件,其符合一個接口

  • 位置類型,從一個基極/抽象類派生的依賴關係,並通過屬性搜索部件

  • (Smelly)testing - 如果你依賴一個不可測試的類(即它不允許你輕鬆地構建一個假的),你可以使用Reflection在類中注入假值 - 這不是很好,並不推薦,但它可以成爲一個方便的工具。

  • 調試 - 傾出裝組件,它們的引用,當前的方法等的列表...

+24

反射被幾乎所有的測試框架用於開始,找到並執行測試... – 2009-09-22 06:00:57

30

有許多用途的反射:

  1. 通過迭代中的對象的屬性。
  2. 調用在運行時定義的方法。
  3. 許多其他的同一脈絡。

但是,我最喜歡使用的反射之一是找到已標記屬性的屬性。

例如,我寫了一些屬性,用於標記我的類中哪些屬性應該使用Lucene進行索引。在運行時,我可以查看任何類,只需查詢類的「標記」屬性即可找出需要索引的字段。

5

如上所述,表現會受到影響。

另一大優點就是可以動態加載組件,執行屬性操作,即使你可能沒有範圍,看看有什麼變化等

使用這個有很多原因。如果需要,這裏是an introduction

20

反射只是在運行時調查對象的一種方式。如果你不需要這樣做,你就不應該使用它。

+2

不知道你爲什麼downvoted,但我修正了:) – leppie 2009-09-22 05:53:59

+0

確實。反思是一個非常強大的資源,但它需要履行其職責,因此除非真正有必要,否則不應使用反思。 – Konamiman 2009-09-22 09:05:18

5

反射通常用於IoC容器。假設你想用「Controller」這個詞註冊每個具體的類。反射使這一塊蛋糕。

我也使用反射操縱私人領域時,單元測試類。

0

由C++即將和已經需要一些簡單的類層次結構,我可以說,is關鍵字是無價的!

class MenuItem : Item { } 

foreach(Item items in parent.ChildItems) { 
    if (item is MenuItem) { /* handle differently */ } 
} 

P.S.是不是反射稍微昂貴,順便說一句?

+3

這不是反射:) 而且,在某些使用情況下只有某些部分很慢。 – leppie 2009-09-22 05:53:02

+0

我的不好,這是類型內省。 – 2009-09-22 22:08:13

+0

C++有類型自省,可以做同樣的事情 – 2015-09-04 07:14:28

8

您可以使用反射來實現一個插件系統,例如。您只需查找文件夾中的所有DLL,並通過反射檢查它們是否實現了某個插件接口。這是我使用反射的主要目的,但我也用它來實現一個通用的自制對象序列化,其中性能並不是最大的關注點。

13

反射允許應用程序收集有關自身的信息,也可以自行操作。它可用於查找程序集中的所有類型和/或動態調用程序集中的方法。

System.Reflection:命名空間包含提供已加載類型,方法和字段的託管視圖的類和接口,並具有動態創建和調用類型的能力;這個過程在.NET框架中被稱爲Reflection。

System.Type: class是.NET Reflection功能的主要類,也是訪問元數據的主要方式。 System.Type類是一個抽象類,並且表示Common Type System(CLS)中的類型。它代表類型聲明:類類型,接口類型,數組類型,值類型,枚舉類型,類型參數,泛型類型定義以及打開或關閉的構造泛型類型。

例如:

using System; 
using System.Reflection; 

static class ReflectionTest 
{ 
    public static int Height; 
    public static int Width; 
    public static int Weight; 
    public static string Name; 

    public static void Write() 
    { 
    Type type = typeof(ReflectionTest); // Get type pointer 
    FieldInfo[] fields = type.GetFields(); // Obtain all fields 
    foreach (var field in fields) // Loop through fields 
    { 
     string name = field.Name; // Get string name 
     object temp = field.GetValue(null); // Get value 
     if (temp is int) // See if it is an integer. 
     { 
     int value = (int)temp; 
     Console.Write(name); 
     Console.Write(" (int) = "); 
     Console.WriteLine(value); 
     } 
     else if (temp is string) // See if it is a string. 
     { 
     string value = temp as string; 
     Console.Write(name); 
     Console.Write(" (string) = "); 
     Console.WriteLine(value); 
     } 
    } 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
    ReflectionTest.Height = 100; // Set value 
    ReflectionTest.Width = 50; // Set value 
    ReflectionTest.Weight = 300; // Set value 
    ReflectionTest.Name = "ShekharShete"; // Set value 
    ReflectionTest.Write(); // Invoke reflection methods 
    } 
} 

Output 

Height (int) = 100 
Width (int) = 50 
Weight (int) = 300 
Name (string) = ShekharShete 
2

非常有用XmlSerialization類依賴反射。您不必自己處理反射以使用序列化,序列化類自己調用反射。但它有助於使用指導對象序列化的屬性來標記代碼。序列化類在運行時使用反射來讀取這些屬性。最後,這個過程似乎很神奇,在應用程序中只需要很少的顯式編碼;這是反映,使便利成爲可能。

XmlSerialization本身非常棒,不僅因爲它是從應用程序創建數據文件的一種非常方便的方式,它也是一種非常簡單的方式,用於爲調試目的而生成程序內部數據模型的人類可讀記錄。

相關問題