2013-02-10 37 views
4

比方說,我們有一個方法:獲得[]爲IEnumerable字符串的輸出參數<string>

public void SomeMethod(out string[] someArray) { // ... } 

有沒有辦法做一些與此類似:

IEnumerable<string> result; 

SomeMethod(out result); 

編輯:問題是,我不'想要將價值綁定到string[],我希望代碼能夠工作,即使方法聲明更改爲SomeMethod(out List<string> outputValue)

+0

需要更多的代碼和一些關於這些變量作用域在哪裏的上下文。 – Matt 2013-02-10 17:06:58

+0

他們在相同的範圍內。如果他們在不同的範圍內,我會表示它。只要讓我知道糾正,如果我誤解了你。 – hattenn 2013-02-10 17:08:53

回答

5

不允許更改輸出參數的類型,因爲不能保證類型安全。這在Eric Lippert's Blog中有詳細說明。

這裏是一個代碼示例一個怎麼會分手類型安全是否會被允許:

IEnumerable<string> result; 

public void Test() 
{ 
    SomeMethod(out result); 
} 

public void SomeMethod(out string[] someArray) 
{ 
    someArray = new string[]; 
    ChangeTheType(); 

    int n = someArray.Length; // BANG!! - someArray is now a List<string> 
} 

public void ChangeTheType() 
{ 
    result = new List<string>(); 
} 

顯然,如果結果不是在同一範圍內調用的someMethod但是編譯器,這只是一個問題不會檢查那個。這是不允許的。

將方法簽名更改爲public void SomeMethod(out IEnumerable<string> someStrings)。您可以在SomeMethod內指定一個string[]someStrings,如果您稍後決定使用List<string>,則可以在不制動呼叫的情況下分配該值。

就我個人而言,我會首先避開參數:public string[] SomeMethod()

+0

謝謝,這解釋了它。這更多的是出於好奇而不是一個設計決定問的問題。剛剛嘗試時,我正在試驗。 – hattenn 2013-02-10 20:44:01

2

我敢肯定,這不是一個最好的辦法,但你可以編寫另一個方法,爲你做這項工作:

public class ClassA 
    { 
     private void SomeMethod(out IEnumerable<string> result) 
     { 
      string[] res; 
      SomeMethod(out res); 
      result = res; 
     } 

     public void SomeMethod(out string[] someArray) 
     { 
      someArray = new string[2]; 
     } 

     void Test() 
     { 
      IEnumerable<string> result; 
      SomeMethod(out result); 
     } 
    } 
+0

問題是我不想將out值綁定到'string []',如果我這樣做,它將被綁定。感謝您的輸入。 – hattenn 2013-02-10 17:29:14

2

你不能做到這一點,周圍有沒有辦法。其中一個原因是CLR不支持out,只有ref。因此out實際上表示爲ref,並且C#編譯器添加了一些特殊規則。

圍繞最簡單(明顯)的方法是創建一個單獨的變量:

string[] resultArray; 

SomeMethod(out resultArray); 
IEnumerable<string> result = resultArray; 

您可以創建一個輔助方法來做到這一點鑄造爲您提供:

public delegate void ActionWithOut<T>(out T result); 

public static void ConvertOut<TBase, TDerived>(
    ActionWithOut<TDerived> method, out TBase result) 
    where TDerived : TBase 
{ 
    TDerived derived; 
    method(out derived); 
    result = derived; 
} 

用法:

IEnumerable<string> result; 
ConvertOut<IEnumerable<string>, string[]>(SomeMethod, out result); 

但是你需要一個單獨的重載(和委託類型)爲每個參數和t他的代碼實際上看起來不太好。 (類型參數是必需的,類型推斷似乎不適用於此代碼。)

相關問題