【问题标题】:What are the benefits of C# 7 local functions over lambdas? [duplicate]C# 7 本地函数相对于 lambda 有什么好处? [复制]
【发布时间】:2017-10-09 22:44:24
【问题描述】:

前几天在我的一个实用程序中,ReSharper 向我暗示了下面的一段代码,说明定义委托 ThreadStart 的 lambda 可以转换为本地函数:

public void Start(ThreadPriority threadPriority = ThreadPriority.Lowest)
{
    if (!Enabled)
    {
        _threadCancellationRequested = false;

        ThreadStart threadStart = () => NotificationTimer (ref _interval, ref _ignoreDurationThreshold, ref _threadCancellationRequested);

        Thread = new Thread(threadStart) {Priority = ThreadPriority.Lowest};
        Thread.Start();
    }
}

因此转化为:

public void Start(ThreadPriority threadPriority = ThreadPriority.Lowest)
{
    if (!Enabled)
    {
        _threadCancellationRequested = false;

        void ThreadStart() => NotificationTimer(ref _interval, ref _ignoreDurationThreshold, ref _threadCancellationRequested);

        Thread = new Thread(ThreadStart) {Priority = ThreadPriority.Lowest};
        Thread.Start();
    }
}

后者比前者有什么好处,只是性能方面的吗?

我已经检查了下面的资源,但在我的示例中,好处并不那么明显:

【问题讨论】:

  • 我会说接近,因为它是基于意见的。但这是一个非常有趣的问题。 :-)
  • 局部函数在一行中支持递归,使用 lambdas 你必须做一些小技巧才能做到这一点,它们也不会像 lambdas 在捕获闭包时那样创建垃圾。
  • @AlKepp 这是基于意见的,问题询问本地功能的好处,否则他们为什么还要引入本地功能。如果 OP 询问您更喜欢哪个,问题将基于意见。显然不是。
  • @M.kazemAkhgary 哦,我没想到,有道理,这可能是一个大专业。

标签: c# .net methods lambda


【解决方案1】:

您链接的第一个网站提到了本地功能的一些好处:
- lambda 导致分配。
- 没有编写递归 lambda 的优雅方式。
- 他们不能使用yield return 可能还有其他一些东西。

一个有用的用例是迭代器:

错误的方式:

public static IEnumerable<T> SomeExtensionMethod<T>(this IEnumerable<T> source) {
    //Since this method uses deferred execution,
    //this exception will not be thrown until enumeration starts.
    if (source == null)
        throw new ArgumentNullException();
    yield return something;
}

正确的方法:

public static IEnumerable<T> SomeExtensionMethod<T>(this IEnumerable<T> source) {
    if (source == null)
        throw new ArgumentNullException();
    return Iterator();

    IEnumerable<T> Iterator() {
        yield return something;
    }
}

【讨论】:

  • 迭代器作为局部函数是局部函数优于 lambdas +1 的巨大优势
  • @Dennis_E:同意这是一个不错的改进!
  • 没有ref, out, params, 可选参数 你能提供参考吗?因为我可以使用refoutparams 和 lambda 的可选参数来实现委托。
  • @PetSerAl 他链接的第一个网站提到了它。我只是没有考虑。你当然是对的。但是你需要先声明一个委托,所以它们不能开箱即用。 .NET 中的标准委托(如FuncAction)都没有refout 参数。
  • @KevinAvignon 正如代码注释中所说,第一个示例在您开始枚举之前不会抛出异常。我们希望立即抛出异常,第二个示例就是这样做的。在 C#7 之前,我们只是做了一个私有方法。所以你有一个公共的SomeExtensionMethod 进行检查和抛出,还有一个私有的方法(通常称为SomeExceptionMethodImpl)有yield return。但是该私有方法也对类的其余部分可见。它只在一个地方使用,所以通过使其成为本地函数,它只能被SomeExtensionMethod使用。
猜你喜欢
  • 1970-01-01
  • 2021-06-02
  • 2016-05-07
  • 2010-11-13
  • 2019-08-13
  • 1970-01-01
  • 2011-01-25
  • 2016-02-08
  • 1970-01-01
相关资源
最近更新 更多