-2

一直在 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
}()

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

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

4

3 回答 3

1

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

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 中的副作用将不受欢迎,因为它们使代码难以遵循。

于 2018-08-01T19:39:55.563 回答
0

您可以在构造函数中初始化您的字段并声明CalculateInitialFoo为本地函数。

private int _foo;

public MyType()
{
    _foo = CalculateInitialFoo();

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

这不会过多地更改您的代码,但您至少可以将方法的范围限制在仅使用它的地方。

于 2018-08-01T19:49:44.057 回答
0

要解决一般情况下的问题,您需要创建然后执行一个匿名函数,从技术上讲,您可以将其作为表达式执行:

int Foo = new Func<int>(() => 
    {
        int x = 0;
        // Perform calculations to get x
        return x;
    })();

你可以通过编写一个辅助函数来清理它:

public static T Perform<T>(Func<T> function)
{
    return function();
}

这让你写:

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

虽然这比第一个要好,但我认为很难说两者都比编写一个函数更好。

在非一般情况下,可以更改许多特定实现以在单行而不是多行上运行。在您的情况下,这样的解决方案可能是可能的,但我们不可能在不知道它是什么的情况下说出来。在某些情况下这是可能的但不受欢迎,而在某些情况下这实际上可能更可取。哪个当然是主观的。

于 2018-08-01T19:41:21.297 回答