使用.NET本身不喜欢的匿名方法?

时间:2013-08-05 10:07:02

标签: c# linq .net-4.0 .net-4.5 anonymous-function

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提供这种匿名方法功能,但不允许以其自己的方式使用它?

3 个答案:

答案 0 :(得分:2)

没有Console.WriteLine的重载接受Func<string> - 事实上,即使您当前的WriteLog方法也不会做任何有用的(因为你' d需要调用委托)。

在接受特定委托的方法存在的地方 - 最突出的是在LINQ中,但在其他地方 - 你确实可以使用lambda表达式或匿名方法来调用它们。

可以使用lambda表达式调用Console.WriteLine,但您需要将其转换为特定的委托类型 - 因为只有从lambda表达式到特定委托或表达式类型的转换,不只是Delegateobject。所以这将有效:

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秒来构建字符串,即使needToWriteLogfalse,而第一个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}}的参数是免费的副作用非常重要(明显忽略)作为副作用的时间,我的意思是“真正的”副作用,比如改变变量值),因为你不知道它们是否真的会被执行。