這不是Calling a method with ref or out parameters from an anonymous method爲什麼在匿名方法中不允許out參數?
愚弄的人,爲什麼出參數沒有匿名方法內不允許我想知道。不允許ref參數對我來說有點意義,但出參數,沒有那麼多。
對此有何看法
這不是Calling a method with ref or out parameters from an anonymous method爲什麼在匿名方法中不允許out參數?
愚弄的人,爲什麼出參數沒有匿名方法內不允許我想知道。不允許ref參數對我來說有點意義,但出參數,沒有那麼多。
對此有何看法
在某些方面,這是一個騙局。 Out
參數是ref
參數。 C#語言使用的值只有一個額外的屬性。禁止它們的原因與ref
參數完全相同。
此處的問題源於使用匿名方法內的匿名方法外聲明的值的效果。這樣做會捕捉lambda中的值,並且出於必要性,將其壽命延長到超出當前函數的壽命。這與具有固定使用壽命的out
參數不兼容。
想象一下,例如out
參數引用堆棧上的局部變量。 lambda可以在將來的任意點執行,因此可以在堆棧幀不再有效時執行。 out
參數意味着什麼?
+1已經開始輸入類似於您最後一段的示例。感謝您節省我的麻煩:) – 2009-10-28 15:12:44
第二段打開了燈泡。謝謝@JaredPar! – 2009-10-28 15:20:49
但是這不適用於其他類型的變量嗎?我的意思是,如果我在位於堆棧中的lambda表達式中使用一個變量,只需訪問某個字段即可。如果lambda表達式在堆棧不再有效時執行,該對象是否已被收集?如果不是,垃圾收集器何時收集該對象? – 2009-10-28 15:40:00
這基本上是與事實有關的匿名委託/ lambda表達式的參數捕獲變量,並捕捉ref
/out
變量不會使在C#/ CLR的任何意義,因爲它需要ref
/out
字段內部。另外請注意,我將這兩個關鍵字配對,因爲它們實際上是相同的。
如果你想在他的博客上有一個完整的解釋,Eric Lippert discussed this design point in detail。 (見段落附近特別是底部)
out
和ref
參數之間的唯一區別是一個out
參數將具有施加到它的[out]
令牌。就CLR而言,它們是同樣的事情。
爲了實現它,編譯器將不得不生成ref
字段,這是不支持的。
如果你仔細想想,你會意識到讓一個匿名方法使用out
參數是沒有意義的。
下面的代碼會怎樣?
static Func<object, object> Mess(out object param) {
param = "Original";
return i => param = i;
}
static Func<object, object> MessCaller() {
object local;
return Mess(out local);
}
static vouid Main() {
Console.WriteLine(MessCaller()("New"));
//The local variable that the lambda expression writes to doesn't exist anymore.
}
'OutAttribute'屬性不適用於C#中out參數。 'OutAttribute'是編組東西時考慮的自定義屬性。 'out'參數由另一個元數據標記(IL中的'[out]')註釋。您可以通過查詢C#代碼中聲明爲'out'的'ParameterInfo'的屬性來驗證這一事實。那裏沒有'[OutAttribute]'。 – 2009-10-28 15:24:42
固定;謝謝。 – SLaks 2009-10-28 15:31:05
我在開發一些錯誤處理代碼時遇到了這個難題。我想將一個引用(out)傳遞給一個會被記錄的錯誤消息。這讓我的匿名方法有機會執行多個檢查,每個檢查都根據需要設置錯誤消息。
我最終爲工作不同的匿名方法編寫了一個新的包裝器。但是,我認爲對某人來說可能有一些價值,那就是我可以簡單地創建一個具有out參數的私有方法,並定義一個委託,並使我的代碼使用它。希望這有助於/激勵某人。
protected delegate void OutStringDelegate(int divider, out string errorText);
protected void codeWrapper(int divider, OutStringDelegate del)
{
string ErrorMessage = "An Error Occurred.";
try
{
del(divider, out ErrorMessage);
}
catch
{
LogError(ErrorMessage);
}
}
public void UseWrapper(int input)
{
codeWrapper(input, codeToCall);
}
private int somePrivateValue = 0;
private void codeToCall(int divider, out string errorMessage)
{
errorMessage = "Nice Error Message here!";
somePrivateValue = 1/divider; // call me with zero to cause error.
}
private void LogError(string msg)
{
Console.WriteLine(msg);
}
我想知道爲什麼你會傳遞一個方法體外的匿名類型,除非你想學習反射的喜悅。 – Will 2009-10-28 15:06:03
原始鏈接問題上的這個答案對此沒有充分回答嗎? http://stackoverflow.com/questions/801147/scope-of-anonymous-methods/801563#801563 – 2009-10-28 15:09:27
@威爾:這與匿名類型無關。 – SLaks 2009-10-28 15:16:48