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

4

3 回答 3

2

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

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

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

Console.WriteLine((Func<string>)(() => "someLogData"));

尽管如此,无论如何这样做也没有用 - 你不想记录委托,你想记录调用委托的结果。

接受代表 IMO没有多大意义,但对于Console.WriteLine灵活的日志记录更有意义,除非您实际上将其写入日志,否则您不想评估字符串。

请注意,您的WriteLog调用本身也可以更简单:

WriteLog(() => "someLogData");
于 2013-08-05T10:09:55.603 回答
1

您需要执行匿名方法来获取字符串。

public void WriteLog(Func<string> s)
{
    Console.WriteLine(s());
}
于 2013-08-05T10:12:31.630 回答
1

这种形式有一个优点:

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.*没有副作用是非常重要的(显然忽略了作为副作用的时间,我的意思是“真正的”副作用,比如改变变量值),因为你不知道他们是否真的会被执行。

于 2013-08-05T10:22:26.267 回答