Monday, December 01, 2008 - 文章

CODE-Reflection範例

Reflection是在執行期間才解析物件類別資訊的技術,在不少場合,要處理的物件類別在編譯時期是無法預知的,或是希望能保留彈性,以便接受包容各種物件。當傳進來的物件參數類別是object,卻又想一探它的底細,就是System.Reflection命名空間神奇工具組上場的時候。

印象中Reflection與編譯期確定型別相比,效率頗差,每次要動用時總有些畏首畏尾的。但我後來發現MS在BCL內,自己倒用Reflection用得很盡興,加上新一代的CPU愈來愈快,效能差異的顯著性正大幅降低。慢慢地我才開始比較大膽應用它解決問題,執行期才動態識別物件的做法,在某些場合大幅簡化程式的複雜度,有時甚至是形成10行Code對100行Code的差距。

每次要寫Reflection都要重新查文件,索性留文一篇給自己也給大家參考。

以下的例子利用Reflection的技術剖析傳入的未知類別object物件,一一巡弋自訂類別SecrectObject的Field、Property,連宣告private的也不放過,呵呵。最後再示範了如何呼叫Method。

using System;
using System.Reflection;
using System.Diagnostics;
 
public class SecretObject
{
    public string PublicProperty { get; set; }
    private string PrivateProperty { get { return "Secrect"; } }
    public string PublicField = "Public";
    private string PrivateField = "Private";
    public static string StaticField = "Static";
    public void SayHello(string name)
    {
        Console.WriteLine("Hello, " + name);
    }
}
 
public class CSharpLab
{
    public static void Test() 
    {
        SecretObject so = new SecretObject();
        so.PublicProperty = "Open";
        Analyze(so);
    }
 
    public static void Analyze(object obj)
    {
        Type t = obj.GetType();
        Console.WriteLine("Type Name={0}", t.Name);
        foreach (FieldInfo f in t.GetFields(
            BindingFlags.Public | BindingFlags.NonPublic |
            BindingFlags.Instance | BindingFlags.Static))
            Console.WriteLine(
                "Field [{0}] = {1}", f.Name, f.GetValue(obj));
        foreach (PropertyInfo p in t.GetProperties(
            BindingFlags.Public | BindingFlags.NonPublic |
            BindingFlags.Instance | BindingFlags.Static))
            Console.WriteLine("Property [{0}] = {1}",
                                p.Name, p.GetValue(obj, null));
        foreach (MethodInfo m in t.GetMethods(
            BindingFlags.Public | BindingFlags.Instance ))
        {
            if (m.Name == "SayHello")
            {
                Console.WriteLine("Method [SayHello] Found!");
                foreach (ParameterInfo a in m.GetParameters())
                    Console.WriteLine(" - Parameter : " + a.Name);
                m.Invoke(obj, new object[] { "Jeffrey" });
            }
        }
    }
}

[程式碼可使用MiniCSharpLab直接執行]

搜尋

Go

<December 2008>
SunMonTueWedThuFriSat
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
 
RSS
【工商服務】
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


BlogLook Score and Rank

Syndication