久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C# 反射/映射學(xué)習(xí)

 Jcstone 2014-09-15

——博客園 老金

最近想研究一下反射,先上網(wǎng)找了找資料,幾乎大部分都是照抄MSDN的內(nèi)容,生澀難懂,幾乎沒(méi)說(shuō),又找了找,發(fā)現(xiàn)一些強(qiáng)人的實(shí)例解析,才稍微有了點(diǎn)門(mén)道,個(gè)人感覺(jué),反射其實(shí)就是為了能夠在程序運(yùn)行期間動(dòng)態(tài)的加載一個(gè)外部的DLL集合,然后通過(guò)某種辦法找到這個(gè)DLL集合中的某個(gè)空間下的某個(gè)類的某個(gè)成員(通過(guò)反射可以訪問(wèn)該類所包含的所有成員,不論成員是公有還是私有),看看網(wǎng)上N人寫(xiě)的實(shí)例:

1.運(yùn)用反射調(diào)用其它程序集中的方法:   
  假設(shè)另一個(gè)工程中的所有類都編譯到一個(gè)dll文件中了,,在這很多的類當(dāng)中,,有一個(gè)類叫StringUtil,名稱空間在HSMP.CommonBasic.Common 代碼如下 :

復(fù)制代碼
namespace lab.CommonBasic.Common
{
    class StringUtil
    {
        public double GetSum(double x, double y)
        {
            return x + y;
        }   
    }
}
復(fù)制代碼

   
  編譯后dll文件的存放路徑是:D:\Test\HSMP.CommonBasic.dll   
  現(xiàn)在的問(wèn)題是,如何通過(guò)程序調(diào)用該dll文件中的GetSum方法   
  大概有以下幾步:

復(fù)制代碼
    //這里要用LoadFrom,,只有在本工程里添加了該dll的引用后才可以使用Load   
    Assembly objAss = Assembly.LoadFrom(@"D:\Test\HSMP.CommonBasic.dll");

    //HSMP.CommonBasic.Common.StringUtil類的全路徑   
    Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil");

    //動(dòng)態(tài)生成類StringUtil的實(shí)例   
    object obj = System.Activator.CreateInstance(t);

    //參數(shù)信息,,GetSum需要兩個(gè)int參數(shù)   
    System.Type[] paramTypes = new System.Type[2];
    paramTypes[0] = System.Type.GetType("System.Int32");
    paramTypes[1] = System.Type.GetType("System.Int32");

    //找到對(duì)應(yīng)的方法   
    MethodInfo p = t.GetMethod("SayHello", paramTypes);

    // 也可以不給類型參數(shù),下面調(diào)用時(shí)給實(shí)參就可以
    MethodInfo p = t.GetMethod("SayHello");

    //參數(shù)值,如果所調(diào)用的方法沒(méi)有參數(shù),不用寫(xiě)這些   
    Object[] parameters = new Object[2];
    parameters[0] = 3;
    parameters[1] = 4;

    //如果沒(méi)有參數(shù),,寫(xiě)null即可,。 
    object objRetval = p.Invoke(obj, parameters);
復(fù)制代碼

   通過(guò)代碼可以看出反射其實(shí)很簡(jiǎn)單。就是動(dòng)態(tài)類型加載,。

   

    以上我們用反射對(duì)靜態(tài)類型做加載,,但如果類是個(gè)范型類該怎么辦呢?其實(shí)方法大同小異,,只是獲取到類型時(shí)需要設(shè)置一下實(shí)際要使用的類型即可,,先看范型類定義:

復(fù)制代碼
namespace lab.CommonBasic.Common
{
    class StringUtil<T,U>
    {
        public string GetSum(T x, U y)
        {
            return x + " and " + y;
        }   
    }
}
復(fù)制代碼

再看反射操作:

復(fù)制代碼
    ... 前面代碼相同

    //HSMP.CommonBasic.Common.StringUtil類的全路徑(范型類最后用 `2 標(biāo)示需要2個(gè)范型類型參數(shù))   
    Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2");

    // 這一步很重要,設(shè)置實(shí)際的范型類型
    t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) });

    //動(dòng)態(tài)生成類StringUtil的實(shí)例   
    object obj = System.Activator.CreateInstance(t);

    ... 后面代碼相同
復(fù)制代碼

 

還有一種情況,,如果類是常類,,但方法是范型方法改怎么辦?非常簡(jiǎn)單:

復(fù)制代碼
    ... 前面代碼相同

    //HSMP.CommonBasic.Common.StringUtil類的全路徑(范型類最后用 `2 標(biāo)示需要2個(gè)范型類型參數(shù))   
    Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2");

    // 這一步要去掉,,因?yàn)轭惒皇欠盒皖愃圆荒芙o類設(shè)置范型類型
    //t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) }); 

    ... 中間代碼相同
 
    // 區(qū)別在這里,把類級(jí)別的范型類型設(shè)置放到方法級(jí)別就可以了,。
    MethodInfo p = t.GetMethod("SayHello");
    MethodInfo p = p.MakeGenericMethod(new Type[2] { typeof(string), typeof(string) });

    ... 后面代碼相同
復(fù)制代碼

  
2.動(dòng)態(tài)加載, 更改, 增加...某個(gè)程序集
  下面例子中, ChangeValue類的myValue本是私有字段, 
  一般情況下在類外部是不能改它的值的, 但利用反射就能直接訪問(wèn)私有字段而不需要通過(guò)包裝器

復(fù)制代碼
class ChangeValue
{
    // 這是私有字段
    private string myValue;

    // 一般只有通過(guò)這樣的公共屬性外面才可能訪問(wèn)私有字段
    public ChangeValue(string str)
    {
        myValue = str;
    }
    public void WriteLine()
    {
        Console.WriteLine("MyValue is: " + myValue);
    }
}

class Test
{
    public static void Main(string[] args)
    {
        // 正常訪問(wèn)
        ChangeValue cv = new ChangeValue("old value");
        cv.WriteLine();

        //反射的方法直接訪問(wèn)私有字段
        Type t = cv.GetType();

        //得到私有字段對(duì)象并賦值
        FieldInfo field = t.GetField("myValue", BindingFlags.NonPublic | BindingFlags.Instance);
        field.SetValue(cv, "new value");

        //輸出的是新值 "new value"
        cv.WriteLine();
    }
}
復(fù)制代碼


    打個(gè)比方, 你要寫(xiě)一個(gè)播放器, 要支持如mp3, wmv, avi...等格式, 你還希望用戶能自己安裝一個(gè)新的格式, 也就是我們常說(shuō)的插件.
在實(shí)現(xiàn)這些, 可能你要將每種格式都寫(xiě)成單個(gè)的解碼程序集, 如 mp3.dll, wmv.dll, avi.dll....  這樣當(dāng)播放時(shí), 根據(jù)擴(kuò)展名去動(dòng)態(tài)調(diào)用相應(yīng)的解碼程序集, 那么這時(shí)你就得用反射去動(dòng)態(tài)加載這些dll了.如: Assembly.LoadFile ("...avi.dll"), 然后通過(guò)反射可以用avi.dll里面定義的類了.
 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多