我目前正在构建一个半复杂的计算器,它基本上是从我提供的 Excel 电子表格转换而来的。
我已经解决了大部分问题,但在 Excel 电子表格中有一部分在 6 行和 7 列之间进行了多次计算,但问题是这些计算无论如何都没有特定的顺序发生。
例如,Row0[Column1]
是使用 (Row2[Column4] * Row2[Column5])
和 Row1[Column4]
计算的> 是使用 (Row4[Column2]/Row5[Column1])
等计算的。您明白了。
我考虑过使用二维数组,但担心这些值将按特定顺序计算,因此在达到它们时没有任何值(value)。据我所知,将首先计算 Row1,然后是 Row2、Row3 等
那么,如果不为我的 Excel 电子表格中的每个单元格创建一个变量(并对其进行适当排序),有没有一种方法可以使用 C# 进行计算?
我非常感谢任何帮助、建议、指点,无论您认为可能是什么 - 我很想听听!
编辑 在实现了 @dtb 提供的 Lazy 类之后,我得到了以下代码。它是我所提供的 Excel 电子表格中内容的直接副本,包括指针和计算。
var sr = new Lazy<decimal>[6, 6];
sr[0, 0] = new Lazy<decimal>(() => sr[1, 0].Value - eNumber);
sr[0, 3] = new Lazy<decimal>(() => sr[0, 4].Value - sr[1, 0].Value - sr[1, 4].Value);
sr[0, 4] = new Lazy<decimal>(() => sr[0, 0].Value * edD);
sr[0, 5] = new Lazy<decimal>(() => sr[0, 0].Value);
sr[1, 0] = new Lazy<decimal>(() => sr[1, 5].Value);
sr[1, 4] = new Lazy<decimal>(() => sr[1, 0].Value * edD);
sr[1, 5] = new Lazy<decimal>(() => sr[2, 0].Value + sr[2, 5].Value);
sr[2, 0] = new Lazy<decimal>(() => eNumber * rRate);
sr[2, 4] = new Lazy<decimal>(() => sr[2, 0].Value * hdD);
sr[2, 5] = new Lazy<decimal>(() => sr[1, 5].Value);
sr[3, 1] = new Lazy<decimal>(() => sr[2, 5].Value);
sr[4, 2] = new Lazy<decimal>(() => eNumber * (ePc / 100) + sr[2, 0].Value * (hlPc / 100) - sr[3, 1].Value);
sr[5, 0] = new Lazy<decimal>(() => (sr[0, 0].Value + sr[1, 0].Value + sr[2, 0].Value) / ePerR);
sr[5, 2] = new Lazy<decimal>(() => sr[5, 0].Value / rLifecycle);
sr[5, 4] = new Lazy<decimal>(() => sr[5, 2].Value);
sr[5, 5] = new Lazy<decimal>(() => sr[5, 0].Value + sr[5, 2].Value - sr[5, 4].Value);
但是我得到以下错误
ValueFactory 试图访问此实例的 Value 属性。
谷歌搜索错误返回了一堆垃圾搜索类型的网站。
马可
最佳答案
看看惰性求值:
var table = new Lazy<int>[2, 2];
table[0, 0] = new Lazy<int>(() => table[1, 1].Value * 2);
table[0, 1] = new Lazy<int>(() => 42);
table[1, 0] = new Lazy<int>(() => 100);
table[1, 1] = new Lazy<int>(() => table[0, 1].Value + table[1, 0].Value);
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
{
Console.WriteLine("Row = {0} Column = {1} Value = {2}",
i, j, table[i, j].Value);
}
注意表格单元格的内容是如何以任意顺序定义的。只要单元格之间没有循环依赖关系,它就会自行计算顺序。
输出:
Row = 0 Column = 0 Value = 284 Row = 0 Column = 1 Value = 42 Row = 1 Column = 0 Value = 100 Row = 1 Column = 1 Value = 142
It becomes slightly more readable with LINQ-to-Lazy:
var table = new Lazy<int>[2, 2];
table[0, 0] = from t in table.AsLazy()
from x in t[1, 1]
select 2 * x;
table[0, 1] = 42.AsLazy();
table[1, 0] = 100.AsLazy();
table[1, 1] = from t in table.AsLazy()
from a in t[0, 1]
from b in t[1, 0]
select a + b;
使用
static class LazyExtensions
{
public static Lazy<TResult> SelectMany<TSource, TCollection, TResult>(this Lazy<TSource> source, Func<TSource, Lazy<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
return new Lazy<TResult>(() => resultSelector(source.Value, collectionSelector(source.Value).Value));
}
public static Lazy<TSource> AsLazy<TSource>(this TSource value)
{
return new Lazy<TSource>(() => value);
}
}
.NET 4.0 的自定义替换 Lazy<T> Class :
sealed class MyLazy<T>
{
private readonly Func<T> valueFactory;
private T value;
private bool valueCreated;
public MyLazy(Func<T> valueFactory)
{
if (valueFactory == null)
{
throw new ArgumentNullException("valueFactory");
}
this.valueFactory = valueFactory;
}
public bool IsValueCreated
{
get { return this.valueCreated; }
}
public T Value
{
get
{
if (!this.valueCreated)
{
this.value = this.valueFactory();
this.valueCreated = true;
}
return this.value;
}
}
}
关于c# - 在 C# 中计算值的数组(从 Excel 转换公式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3712954/