2010-01-29 102 views
9

我有一個類,主要是一個大陣列和一些相關的家務包裝。我有一個函數,它需要一個ref參數。當我將該類的一個實例傳遞給該函數時,我想要發送該數組。傳遞一個明確的演員作爲參考參數(C#)

我認爲明確的演員。假設我有一些具有byte [] ref參數的函數。

public void SomeFunction(ref byte[] someBytes); 

而且我有一些重載顯式類型轉換的類。

class SomeClass 
    { 
     byte[] someBytes; 
     public static explicit operator byte[](SomeClass someInstance) 
     { 
      return someInstance.someBytes; 
     } 
    } 

現在,我要打電話與類的函數作爲參數

SomeClass someInstance = new SomeClass(); 
    SomeFunction(ref (byte[]) someInstance); 

編譯器會抱怨「ref或out參數必須是可分配的變量」。我不確定我是否沒有正確地按摩編譯器,或者如果你真的無法做到這一點。

我認爲屬性或函數的返回值,但你不能傳遞那些由REF(和教育自己後,我明白爲什麼...)

我不想讓陣列公共領域,但確實符合編譯器的要求。 我我可以創造一個局部變量來引用與陣列,但是這是一個額外的代碼行前,每個函數調用後...

編輯:它可能是值得注意的是,SomeFunction被寫了第三方,我無權改變它。更糟的是,我認爲他們的參數實際上不需要參考...

回答

9

一個強制轉換不是一個可指定的變量;你正從你的顯式轉換運算符傳遞一個返回值。

你可以把它當作一個參考之前創建一個變量保持正常投值:

SomeClass someInstance = new SomeClass(); 
byte[] someBytes = (byte[])someInstance; 
SomeFunction(ref someBytes); 

注意,它現在是someBytes變量,它可能會重新分配。如果您想要重新分配someInstance的內部值,您必須採取措施在SomeFunction的呼叫之後以某種方式重新分配someInstance.someBytes

+0

所以事實證明,切實可行的解決辦法要麼是公共領域或短的方法,其唯一目的是爲了掩蓋一些局部變量的創建來傳遞。我做了一些更多的挖掘和仿製藥可能有幫助也是。 – ajs410 2010-02-01 14:45:48

+0

對,一個簡單的setter就足以更新someInstance。作爲替代,您可以創建一個SomeFunction作爲參數的接口,SomeInstance實現並通過該接口實現您的邏輯。 – 2010-02-01 15:31:26

1

你不能這樣做,你需要首先將你的對象轉換成變量的結果。

考慮下面的代碼,如果你問被允許:

public void SomeFunction(ref byte[] someBytes) 
{ 
    someBytes = new byte[] { 1, 2, 3 }; 
} 

SomeClass someInstance = new SomeClass(); 
SomeFunction(ref (byte[]) someInstance); 
// uh-oh, what is "someInstance" now? 

爲什麼參數標有「裁判」,什麼問題是,你想在這裏解決?

+0

由於原始的第三方開發人員正在將C++庫移植到.NET,所以參數標記爲ref。我試圖解決的問題是圍繞ref跳舞,而不是使someBytes成爲公共字段或創建局部變量。我選擇了「明確演員」,因爲我知道家政領域將會丟失。我希望someInstance只是將someBytes的引用傳遞給SomeFunction。與使用公共字段沒什麼不同,但強制顯式轉換會使其不易被濫用。 – ajs410 2010-01-29 23:31:34

+1

那麼,「參考」和「出」參數需要一個支持變量,真的沒有辦法繞過,所以你只需要定義變量,因爲你已經發現了。你當然可以在你自己的類中創建shim方法來爲你做這個翻譯,然後調用這些方法,然後進行轉換,存儲一個變量,並調用實際的方法,但那可能會不是一個好的解決方案。 – 2010-01-29 23:46:10

+0

最終的解決方案實際上涉及創建對byte []的引用的本地副本並重新創建本地副本。這在技術上違反了裁判點,但我敢肯定,第三方程序員認爲C#中的ref與C++中的&相同,這是不正確的。 – ajs410 2010-02-01 14:52:39

1

可以在C#中用作ref參數的值範圍受CLR允許的限制。它在CLI規範中的第12.4.1.5.2和12.1.6節中進行了說明。1,並且包括

  • 參數的對象的當前方法
  • 局部變量
  • 成員字段
  • 靜電場
  • 數組元素

的鑄造不適合任何的這些因此不能用作ref的值。在通過引用傳遞它之前,您需要將它分配給像本地一樣的值。

+0

感謝您參考規格!我一段時間都沒有涉足C#,所以從某種意義上說,當我全面探索該語言的各種特性時,這更像是一個學術問題......並且確實有很多。 – ajs410 2010-02-01 14:48:13

0

你是否真的必須施放ref參數?在我的情況下,這樣的工作很好。

byte[] someInstance = (byte[])new SomeClass(); 
SomeFunction(ref someInstance);