将变量分配给表达式C#

时间:2019-01-08 22:14:55

标签: c#

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

谢谢

编辑:

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

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;
    }
}

如果变量和比较对于使用此函数的对象而言不是局部的(例如,在引用另一个对象变量的对象中),将可以正常工作。我对此表示怀疑,因为它只会是变量的副本,而不是原始变量存储位置的指针/引用。

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

这背后的原因是我正在为设计师开发一个高度结构化和模块化的系统,其中一项要求是根据其输入创建一个函数,该函数首先进行计算,然后在运行时使用。欢迎使用其他方法。

谢谢。

2 个答案:

答案 0 :(得分:5)

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

() => numResources > 50

在这里,numResources引用了一个变量,该变量在代码的其他位置声明,但是在创建匿名函数的作用域中可见。这会导致numResources上的closure,在C#中,这意味着匿名函数可以随时访问该变量,即使该函数是从没有numResources的位置调用的也是如此通常可用。

现在,为了将匿名函数分配给变量,以便可以对其进行多次求值或在方法之间传递,必须使用delegate类型。如今,通常使用Func<TResult,...>Action<...>类型之一来声明代表。

由于示例表达式没有参数并返回bool,因此您应将变量声明为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)
        }
    }

答案 1 :(得分:1)

我不确定您要达到什么目的,但是可以通过getter实现查看属性,如下所示:

public class Test 
{
   private int _numResources;
   public bool CanBuild 
   { 
      get
      {
        return _numResources == 50;
      }
   }
}