C 反射破壞單例

2021-09-25 10:19:23 字數 2134 閱讀 5199

單例大家都不陌生,程式從開啟到死亡過程中只能存在乙個例項,即存在不可建立,今天給大家介紹一種打破這種模式的方法,在程式執行中建立無數個單例例項物件。

關於單例模式模糊或者不懂的可以參考c#單例模式

上文我們講到了反射的基本操作,例項化物件、屬性、方法、特性等操作,可以參考c#反射

咱們切入正題,單例有兩種,一種是程式載入時建立,一種是使用時建立,我們這裡主要是建立乙個載入時建立的單例。我們通過反射來破壞這個單例,建立單例物件

class singleton

public static singleton singl()

return inntleton;

}}

然後通過反射建立這個單例物件並且對比

//呼叫私有方法建構函式

var ass = assembly.load("textcord");

var type = ass.gettype("textcord.singleton");

var singletoncreate = activator.createinstance(type, true);

var singleton = singleton.singl();

console.writeline(object.referenceequals(singleton, singleton.singl()));//true

console.writeline(object.referenceequals(singleton, singletoncreate));//false

class genclass

}

呼叫

var ass = assembly.load("textcord");

//反射呼叫泛型

var type_q = ass.gettype("textcord.genclass`1");

var typemake = type_q.makegenerictype(new type );

var genclass = activator.createinstance(typemake);

var note = typemake.getmethod("note",new type );

note.invoke(genclass, new object );

這裡有幾個重要的部分

我們在獲取這個泛型的時候後面跟一些字元"`1",那麼這個是什麼意思呢?其實這個就是我們編譯**成il的時候,系統指定的乙個類似佔位符的東西,一般來說乙個引數就是"`1",tclass兩個就是"`2"。

第二個注意的地方就是,我們初始化這個t的時候需要呼叫一下makegenerictype()方法,用於初始化型別t,就好像我們new一樣

//如同這樣

var genclass = new genclass();

第三個主要的就是,我們動態呼叫方法,我們一般在createinstance的時候就是建立反射物件的例項,通過強轉或者使用動態型別呼叫方法,這裡我們是通過動態的方式呼叫,示例如下

//反射呼叫泛型

var type_q = ass.gettype("textcord.genclass`1");

var typemake = type_q.makegenerictype(new type );

var genclass = activator.createinstance(typemake);

var note = typemake.getmethod("note",new type );

note.invoke(genclass, new object );

//強轉

genclassy = (genclass)activator.createinstance(typemake);

y.note("yyyyy");

//動態型別

dynamic d = activator.createinstance(typemake);

d.note("ddddd");

readResolve 解決反射破壞單例

具體的操作和測試在單例的部落格中都有提到 單例模式的幾種寫法 單例的寫法和測試結果此片文章不再演示,直接去找readresolve 是怎樣防止破壞單例的。在測試 中用到了 objectinputstream 進入到這個 中,找到 片段 走到readobject 方法中。在readobject 方法中...

反射機制會破壞單例模式嘛

現在已經標準的實現了單例模式 單檢查鎖,雙檢查鎖,列舉 如果我們通過反射機制呼叫,是否會產生多個例項,即破壞了單例模式。反射模式,呼叫方法是不會破壞單例模式,因為反射方法同樣受鎖 邏輯的保護。呼叫建構函式會破壞單例模式,因為構造方法只是private 修飾,防止外部類訪問,但是反射方法訪問,不受限制...

防止利用暴力反射破壞單例模式

單例模式的實現是將構造私有化,然後內部維護乙個物件,但是還是可以通過暴力反射建立多個例項,如下 我以上篇文章講的靜態內部類方式實現單例模式為例 package com.hy.practice import sun.security.jca.getinstance author hy classnam...