首页 > 解决方案 > 将变量分配给表达式 C#

问题描述

是否可以将变量分配给 C# 中的表达式,这样我就不必为它编写方法?例如,名为 canBuild 的变量等于表达式“numResources > 50”。每当调用该变量时,它都会重新计算它的值。我试过研究 lambdas,但我不太了解文档。

谢谢

编辑:

这是我尝试使用 lamdas 的尝试:

public void setStateFloat(float variable, float comparison, int compareType)
{
    Func<bool> stateEval;
    switch(compareType)
    {
        case 0:
            stateEval = () => variable < comparison;
            break;
        case 1:
            stateEval = () => variable > comparison;
            break;
        case 2:
            stateEval = () => variable == comparison;
            break;
    }
}

如果变量和比较不是使用此函数的对象的本地变量(如在引用另一个对象变量的对象中),这将起作用。我对此表示怀疑,因为它只是变量的副本,而不是指向原始变量存储位置的指针/引用。

另外,如果我想存储对该函数的引用,我该怎么做?

这背后的原因是我正在为设计师开发一个高度结构化和模块化的系统,其中一个要求是从他们的输入中创建一个函数,该函数最初是计算出来的,然后在运行时使用。欢迎替代方法。

谢谢。

标签: c#

解决方案


您将无法完全避免方法的概念,但 C# lambda 表达式为创建可以按照您建议的方式使用的匿名函数提供了一种很好的简洁语法。在您的示例中,表达式没有输入参数,因此看起来像这样:

() => numResources > 50

在这里,numResources指的是在代码中其他地方声明的变量,但在创建匿名函数的范围内可见。这会导致over闭包numResources,这在 C# 中意味着匿名函数可以随时访问该变量,即使该函数是从numResources通常不可用的位置调用的。

现在,为了将匿名函数分配给一个变量,以便它可以被多次评估或在方法之间传递,必须使用委托类型。如今,委托通常使用Func<TResult,...>Action<...>类型之一声明。

由于您的示例表达式没有参数并返回 a bool,因此您将变量声明为 type Func<bool>。在一个语句中结合声明和初始化,这变成:

Func<bool> canBuild = () => numResources > 50;

请注意,类型需要显式声明,var在这里不起作用。现在你有了一个变量canBuild,你可以像使用方法名一样使用它:

bool result = canBuild();

例子

// Declare and initialize numResources
int numResources = 42;

// Declare and initialize a delegate and the anonymous function
Func<bool> canBuild = () => numResources > 50;

// Invoke the function    
bool result = canBuild();  // False this time, since 42 < 50

// Update numResources
numResources = 75;

// Invoke the function again 
bool result = canBuild();  // True this time

局部变量闭包示例

以下示例演示了 C# 闭包如何使变量共享,以便匿名函数实际上引用原始变量,而不仅仅是副本:

    class Program
    {
        public static void CreateAnonFuncs(out Func<int> getNumber, 
                                           out Action<int> setNumber)
        {
            // Declare a local variable
            int localNum = 42;

            // Create anonymous functions that reference the local variable
            getNumber = () => localNum;
            setNumber = (n) => { localNum = n; };

            // Let's update the local variable afterwards
            localNum = 21;
        }

        public static void Main()
        {
            // Call the method that creates the functions
            CreateAnonFuncs(out var getter, out var setter);

            // Now invoke the functions to prove that the variable is shared
            Console.WriteLine($"Value from getter: {getter()}"); // 21 (not 42)
            setter(99);
            Console.WriteLine($"New value from getter: {getter()}"); // 99 (not 21)
        }
    }

推荐阅读