首页 > 解决方案 > 这可以通过 Lambda/Block 初始化来简化吗?

问题描述

一直在 Swift 和 C# 之间来回切换,我不确定我是否忘记了某些事情,或者 C# 是否不容易支持我所追求的。

考虑这个计算初始值的代码Foo

// Note: This is a field on an object, not a local variable.
int Foo = CalculateInitialFoo();

static int CalculateInitialFoo() {
    int x = 0;
    // Perform calculations to get x
    return x;
}

有没有办法做这样的事情,而不需要创建单独的一次性使用函数,而是使用即时执行的 lambda/block/whatever?

在 Swift 中,这很简单。您使用立即执行的闭包(花括号)(左括号和右括号),如下所示:

int Foo = {
    int x = 0
    // Perform calculations to get x
    return x
}()

它清晰、简洁,不会使对象的接口与仅用于初始化字段的函数混淆。

注意:要清楚,我想要计算的属性。我正在尝试初始化一个需要多个语句才能完全完成的成员字段。

标签: c#initializationexpressionmember-initialization

解决方案


我不建议这样做,但您可以使用匿名函数来初始化

int _foo = new Func<int>(() =>
{
    return 5;
})();

您是否有理由希望使用 lambdas 而不是命名函数或作为计算属性来执行此操作?

我假设您想避免计算属性,因为您想稍后修改该值,或者计算很昂贵并且您想缓存该值。

int? _fooBacking = null;

int Foo
{
    get
    {
        if (!_fooBacking.HasValue)
        {
            _fooBacking = 5;
        }

        return _fooBacking.Value;
    }
    set
    {
        _fooBacking = value;
    }
}

这将使用您在第一次获得条件时评估的内容,同时仍允许分配值。

如果您删除 setter,它会将其转换为缓存计算。不过,在使用这种模式时要小心。属性 getter 中的副作用将不受欢迎,因为它们使代码难以遵循。


推荐阅读