Mar*_*rko 1 c# excel calculated-columns lazy-evaluation multidimensional-array
我目前正在构建一个半复杂的计算器,它基本上是我提供的Excel电子表格的转换.
我已经把大部分内容钉在了但是在Excel电子表格中有一个部分,其中在6行和7列之间进行了多次计算,但问题在于计算没有按照特定的顺序发生.
因此,例如,Row0[Column1]
使用计算,并使用(Row2[Column4] * Row2[Column5])
等Row1[Column4]
计算(Row4[Column2] / Row5[Column1])
..你得到了想法.
我曾考虑使用2D数组,但我担心这些值会按特定顺序计算,因此在达到它们时没有任何价值.据我所知,ROW1将首先计算,然后行2,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);
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误
ValueFactory attempted to access the Value property of this instance.
谷歌搜索错误已经返回了一堆垃圾搜索类型的网站.
马尔科
看看懒惰评估:
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);
}
Run Code Online (Sandbox Code Playgroud)
注意表单元格的内容是如何以任意顺序定义的.只要单元格之间没有循环依赖关系,它就会找出顺序本身.
输出:
Row = 0 Column = 0 Value = 284 Row = 0 Column = 1 Value = 42 Row = 1 Column = 0 Value = 100 Row = 1 Column = 1 Value = 142
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;
Run Code Online (Sandbox Code Playgroud)
运用
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);
}
}
Run Code Online (Sandbox Code Playgroud)
.NET 4.0的Lazy <T>类的自定义替换:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1788 次 |
最近记录: |