这种形式有一个优点:
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
让我们想象它在里面写成:
public void WriteLog(Func<string> s)
{
if (needToWriteLog)
{
Console.WriteLine(s);
}
}
现在,假设您这样称呼它:
WriteLog(() => StringThatNeedsFiveSecondsToBuild())
让我们将其与仅接受 astring
作为参数的类似 WriteLog 进行比较:
WriteLog(StringThatNeedsFiveSecondsToBuild())
第二个WriteLog
总是花费 5 秒来构建字符串,即使needToWriteLog
是 是false
,而第一个只会在它是 时构建它true
。
现在,将其与Console.WriteLine
:进行比较,Console.WriteLine
将始终打印其内容,因此无需使用委托,因为将始终花费 5 秒。
在 C# 中,有一些方法相似,例如 和 家族的方法Debug.*
,Trace.*
但它们是不同的。你像这样使用它们:
Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
诀窍是它们的定义如下:
[ConditionalAttribute("DEBUG")]
public static void WriteLine(string value)
因此,如果DEBUG
未定义,则将整个Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
删除,即使它有一些副作用(例如花费 5 秒 :-))
所有这些都显示了其他东西:传递给你的代表WriteLog
和传递给你的参数Debug.*
并且Assert.*
没有副作用是非常重要的(显然忽略了作为副作用的时间,我的意思是“真正的”副作用,比如改变变量值),因为你不知道他们是否真的会被执行。