我想保存"说明"如何在以后确定值,而不是在当前时间保存实际值。 这甚至可能吗?
一个简单的C#示例:
int[] myArray = new int[2];
Dictionary<string, int> myDictionary = new Dictionary<string, int>();
//dictionary type can be changed if required
myArray[0] = 1;
myArray[1] = 2;
myDictionary.Add("total", (myArray[0] + myArray[1]) ); // Don't evaluate the value now
myArray[0] = 3;
myArray[1] = 4;
Console.WriteLine("total 2 = " + myDictionary["total"]); // Evaluate the value now
//Desired output: 7 (3+4), actual output = 3 (1+2)
答案 0 :(得分:1)
您可以使用(expression bodied read-only) properties:
public int[] MyArray { get; set; }
public string CurrentResult => $"total: {MyArray.Sum()} ({string.Join("+", MyArray)})";
如果您需要本地变量,可以使用local functions:
string GetCurrentResult() => $"total: {MyArray.Sum()} ({string.Join("+", MyArray)})";
MyArray[0] = 1;
MyArray[1] = 2;
Console.WriteLine(GetCurrentResult()); // total: 3 (1+2)
MyArray[0] = 3;
MyArray[1] = 4;
Console.WriteLine(GetCurrentResult()); // total: 7 (3+4)
如果您不使用C#7,可以使用Func<string>
代理:
Func<string> GetCurrentResult = () => $"total: {MyArray.Sum()} ({string.Join("+", MyArray)})";
答案 1 :(得分:1)
您正在寻找Lazy<T>
。在通过Func<T>
属性访问它之前,它不需要评估Value
。评估完成后,将存储结果以供进一步访问。因此,您的代码可能类似于:
int[] myArray = new int[2];
var total = new Lazy<int>(() => myArray.Sum());
myArray[0] = 1;
myArray[1] = 2;
myArray[0] = 3;
myArray[1] = 4;
Console.WriteLine("total = " + total);
Console.WriteLine("total = " + total.Value);
Console.WriteLine("total = " + total);
此代码的输出为:
total = Value is not created.
total = 7
total = 7
请注意,在不调用total.Value
的情况下,结果不是int
,而是告诉我们表达式尚未被评估的消息。调用total.Value
后,对total
的后续访问会产生值(由于ToString()
中的隐式Console.WriteLine()
调用)。
使用Lazy<T>
的好处是值是持久的,而不是每次访问时都重新计算。这使得它非常适合每次使用类时可能无法访问的类中的属性/字段,但需要很长时间才能生成值。
Lazy<T>
并不完全是他们想要的。如果您总是希望每次访问时都要评估表达式,那么您需要一个方法或Func<T>
。所以想象你有这样一个类:
public class MyClass
{
public int[] Vals {get;set;}
}
如果您想定义获取Vals
总和(例如)的自定义方式,您可以选择几个简单的选项。
public class MyClass
{
public int[] Vals {get;set;}
public int SumOfVals()
{
return Vals.Sum();
}
}
如果你选择类方法,你可以(可以想象)使类通用(MyClass<T>
)并使用虚拟/抽象方法来实现具体的SumOfVals
方法。
Func<T>
public class MyClass
{
public int[] Vals {get;set;}
public Func<int[], int> SumOfVals { get;set; }
}
现在,每次实例化类时,都可以将SumOfVals
设置为某个自定义函数。如果你没有把它设置为任何东西,如果你试图对它做任何事情,你将得到一个NullReferenceException。
Func<T>
内联实施var vals = new int[2];
var sumVals = new Func<int[], int>((arr) => arr.Sum());
Console.WriteLine(sumVals(vals));
这可能是最灵活的,但这可能导致一些意大利面条代码。我建议只在类中调用MyClass
或在MyClass
中创建方法来处理此逻辑。