2013-05-16 84 views
1

我有一個有趣的場景,其中我構建了一個驗證檢查系統,它以List<Tuple<Func<bool>, string>>的形式維護一系列需求,其中Func應該在驗證失敗時返回true,否則返回false。字符串是一個相應的拒絕描述,描述測試失敗時的情況。lambda中的字符串範圍

在類似下面的驗證系統更簡單的測試很簡單:

validationChecks.Add(Tuple.Create<Func<bool>, string>(() => 
    value1 == requiredValue, "value 1 did not have the required value")); 

我努力理解變量的拉姆達爲Func鍵內的範圍,更先進的方案,其中拒絕字符串是在調用系統的另一部分時計算出來的。該方案看起來是這樣的:

string rejectionString = null; 
validationChecks.Add(Tuple.Create<Func<bool>, string>(() => { 
    rejectionString = CallToAnotherMethodThatReturnsString(parameter); 
    if (rejectionString != null) { 
     return true; 
    } else { 
     return false; 
    } 
}, rejectionString)); 

編輯:通過測試,發現當這種檢查失敗的rejectionString從元組仍然是零。我想要使​​用由CallToAnotherMethod生成的rejectString來代替,有沒有什麼辦法可以使用ref或其他方式來做到這一點?我需要Func的代碼能夠影響Tuple的Item2內的字符串的值。

問題是 CallToAnotherMethodThatReturnsString內部的代碼可能是我只想執行一次的代碼。但是,如果檢查失敗,我想使用從它返回的字符串作爲我在Tuple中的拒絕描述。在這一點上,我無法告訴我在第二個示例中使用 rejectionString會產生什麼效果? Tuple中的rejectString是否總是爲空?或者如果 CallToAnotherMethodThatReturnsString返回一個不同的值,它會被更新?

+2

當您運行示例代碼什麼是你的意見(或各種測試中的變化)?你發現了什麼? –

+0

好點,我在第二個例子中硬編碼了一個字符串值來代替CallToAnotherMethodThatReturnsString,並且來自失敗測試的拒絕字符串爲空。這並不是我所希望的...... –

+0

正如你已經並將繼續發現的那樣,關閉外部變量是非常棘手的,而且在循環中做事情時人們通常不會有成功的事情(你的列表可能會給自己帶來好處至)。如果您希望消息根據函數結果而變化,我會建議在此重新考慮您的策略。但是誰知道,也許有人會有另一種想法。 –

回答

1

只是一個想法,可能工作。我想如果你改變你的第二個Tuple參數爲返回字符串而不是字符串值的Func,你可以接近你所需要的。

string rejectionString = null; 
validationChecks.Add(Tuple.Create<Func<bool>, Func<string>>(() => 
{ 
    rejectionString = CallToAnotherMethodThatReturnsString(parameter); 
    if (rejectionString != null) { 
     return true; 
    } else {return false;} 
}, 
()=>rejectionString)); 

在第一種情況下,您的驗證檢查將被設置爲

validationChecks.Add(Tuple.Create<Func<bool>, Func<string>>(() => value1 == requiredValue,()=>"value 1 did not have the required value")); 

而且你的驗證邏輯則

if(validationChecks[0].Item1()==false) 
var error = validationChecks[0].Item2(); 
+0

嗯,這是一個有趣的建議,今天下午我會玩弄它,看看我能否做到我所需要的。感謝您的想法!如果解決問題,我會將其標記爲答案。 +1現在 –

+0

哇謝謝!經過一些測試,這似乎是完美的。絕對要學習更​​多關於lambda表達式和捕獲變量的工作方式。你搖滾 –

+1

@JesseCarter太棒了..我認爲你的問題更多是因爲字符串是如何工作的......字符串是一個引用類型,但是不可變,所以其行爲類似於值類型。在你創建元組的時候,元組得到了一個在創建Tuple時爲null的rejectString的副本。稍後更改rejectString不會更改存儲在元組中的字符串,無論更改rejectString變量,您總是從Item2中獲得null。 – jure