2017-08-08 50 views
0

我在舊系統上進行維護,並在.Net類中找到以下實現(GetMethod只是一個硬編碼示例,它來自config xml文件)。我把它改成正常的方法調用,使看它是否將工作和做:InvokeMember vs普通方法調用

GetMethod = "ListChanges"; 

DataSet dsData = null; 
Type currType = GetType(); 
dsData = currType.InvokeMember(GetMethod, 
     BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, 
       null, 
       this, 
       new object[] {oWS}) as DataSet; 

VS

DataSet dData = ListChanges(<Some class> var); //ListChanges defined in the class!! 

我讀過InvokeMember提供一定的約束力的約束上,但看着這我不明白爲什麼這會改善代碼而不是普通的方法調用?

+1

我強烈懷疑它試圖調用通常無法訪問的成員,例如一個私人的。也許那個成員後來被公開了。 –

+1

我可以想象的唯一場景是什麼使得任何一種意義(如在,不只是與直接調用方法相同的東西)是當類是使用繼承的類型層次結構的一部分時,「ListChanges」不是虛方法,但它仍然存在於派生類中(使用'new'來映射基類)。在這種情況下,'GetType()。InvokeMember()'跳舞是調用派生方法的(可怕的)方式。除此之外,其中沒有意義。也許'ListChanges'曾經是基類的私有或受保護的成員,或者開發人員可能只是想「使用它」。 –

+0

謝謝你們OP。兩者都有道理。不幸的是我無法證實兩者。對我來說,它看起來不必要的複雜。 InvokeMember不會因爲反射而不是正常的函數調用而增加開銷嗎? –

回答

0

這是沒有接口的相同方法名稱模式的情況。您有多個編譯器生成的類(從強類型DataSet等),

class A { 
    public Changes ListChanges(Object a){ 
     ... 
    } 
} 

class B { 
    public Changes ListChanges(Object a){ 
     ... 
    } 
} 

兩個類A和B具有與方法名「ListChanges」相同的方法簽名,但都沒有實現接口。

開發人員可能已經通過使用反射來有效地調用方法,假設您可以輕鬆使用此方法而無需擔心類型。

通常我們會定義partial類併爲生成的類添加接口,但可能這個代碼很舊(類型化數據集很舊),在開發時並不存在partial,編寫自定義代碼生成器也會很多代碼只是簡單地調用單一方法。