I am trying to learn the anonymous method and tried out this sample.
因此,每当我尝试调用WriteLog函数时,我都可以使用
()=> { return "someLogData" };
优点是,我不需要单独的功能,可以保存代码行。
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
但是,与
等功能相同的情况也是如此Console.WriteLine( ()=> {return "someString" } );
为什么.NET提供这种匿名方法功能,但不允许以其自己的方式使用它?
答案 0 :(得分:2)
没有Console.WriteLine
的重载接受Func<string>
- 事实上,即使您当前的WriteLog
方法也不会做任何有用的(因为你' d需要调用委托)。
在接受特定委托做的方法存在的地方 - 最突出的是在LINQ中,但在其他地方 - 你确实可以使用lambda表达式或匿名方法来调用它们。
您可以使用lambda表达式调用Console.WriteLine
,但您需要将其转换为特定的委托类型 - 因为只有从lambda表达式到特定委托或表达式类型的转换,不只是Delegate
或object
。所以这将有效:
Console.WriteLine((Func<string>)(() => "someLogData"));
但是,无论如何这样做都没有用 - 你不想记录委托,你想记录调用委托的结果。
Console.WriteLine
接受委托IMO对非常很有意义,但对于更灵活的日志记录更有意义,你不想评估字符串除非你真的要将它写入日志。
请注意,您的WriteLog
来电也可以更简单:
WriteLog(() => "someLogData");
答案 1 :(得分:1)
您需要执行匿名方法才能获取字符串。
public void WriteLog(Func<string> s)
{
Console.WriteLine(s());
}
答案 2 :(得分:1)
这种形式有一个优点:
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
让我们想象一下,在里面它写成:
public void WriteLog(Func<string> s)
{
if (needToWriteLog)
{
Console.WriteLine(s);
}
}
现在,让我们说你这样称呼它:
WriteLog(() => StringThatNeedsFiveSecondsToBuild())
让我们将它与只接受string
作为参数的类似WriteLog进行比较:
WriteLog(StringThatNeedsFiveSecondsToBuild())
第二个WriteLog
将始终花费5秒来构建字符串,即使needToWriteLog
为false
,而第一个true
只会在Console.WriteLine
时构建字符串。
现在,将其与Console.WriteLine
进行比较:Debug.*
将始终打印其内容,因此无需使用委托,因为将始终花费5秒。
C#中有一些类似的方法,系列Trace.*
和Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
,但它们是不同的。你像这样使用它们:
[ConditionalAttribute("DEBUG")]
public static void WriteLine(string value)
诀窍是它们的定义如下:
DEBUG
因此,如果未定义Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
,则会移除整个WriteLog
,即使它有一些副作用(比如花费5秒:-))
所有这些都显示了其他内容:您传递给Debug.*
的代表以及传递给Assert.*
和{{1}}的参数是免费的副作用非常重要(明显忽略)作为副作用的时间,我的意思是“真正的”副作用,比如改变变量值),因为你不知道它们是否真的会被执行。