我有一个与此类似的代码块:
spark.sql("SELECT udafName(V) as aggV FROM data")
但是,List<Object> returnObjDataLine = new List<object>();
foreach (var tuple in dataPerTime)
{
returnObjDataLine.Clear();
returnObjDataLine.Add(tuple.Item1);
foreach (var line in PlotLines)
{
if (tuple.Item2.Equals(line.Key))
{
returnObjDataLine.Add(tuple.Item3);
}
else
{
returnObjDataLine.Add(null);
}
}
returnObjData.Add(returnObjDataLine);
}
方法会清除已经添加到Clear()
字典中的数据。如果有10,000个元组,则循环运行之后,returnObjData
将包含10,000个添加的最后一个数据片段的实例(returnObjData
在最后一次迭代之后不被调用)。
如果我修改代码以在每次迭代中创建一个新列表:
Clear()
加载循环可以正常工作,但是这看起来非常昂贵,因为如果不需要十万次迭代,则可能需要十秒。每次创建一个新对象似乎效率低下。
foreach (var tuple in dataPerTime)
{
List<Object> returnObjDataLine = new List<object>();
returnObjDataLine.Add(tuple.Item1);
foreach (var line in PlotLines)
{
if (tuple.Item2.Equals(line.Key))
{
returnObjDataLine.Add(tuple.Item3);
}
else
{
returnObjDataLine.Add(null);
}
}
returnObjData.Add(returnObjDataLine);
}
我缺少什么?是否需要先调用某种“提交”?
答案 0 :(得分:-1)
看起来您需要做的是拥有一个临时列表和一个长期列表...类似这样的东西:
List<Object> longTermObjects = new List<object>();
foreach (var tuple in dataPerTime)
{
List<Object> returnObjDataLine = new List<Object>();
returnObjDataLine.Add(tuple.Item1);
foreach (var line in PlotLines)
{
if (tuple.Item2.Equals(line.Key))
{
returnObjDataLine.Add(tuple.Item3);
}
else
{
returnObjDataLine.Add(null);
}
}
longTermObjects.Add(returnObjDataLine);
}
这将为您在每次迭代时提供一个干净的returnObjDataLine,而不会删除longTermObjects中的引用项。
编辑以添加引用类型信息:
默认情况下,.NET将对象的1个副本存储到内存中,然后在您使用该对象的任何位置“引用”该对象。请看以下示例:
int A = 1;
int B = A;
Console.WriteLine($"A = {A}");
Console.WriteLine($"B = {B}");
A = 0;
Console.WriteLine($"A = {A}");
Console.WriteLine($"B = {B}");
结果:
A = 1
B = 1
A = 0
B = 0
为什么要问第四行的B = 0?因为B引用了A,所以它不包含A的实际值,所以当A更改时,B也随之更改。
如果我希望B仅包含A的值,则需要一种方法来创建新的“值”而不是引用。每种对象类型的执行方式不同。一种方法,可能不是最好的方法,例如:
int B = int.Parse(A.ToString());
将A转换为表示A的值的字符串,然后使用Parse将其转换为新的int。现在,我将值存储在B中,而不仅仅是引用。
如果我想对一个对象表做同样的事情,那么我将不得不做这样的事情:
List<MyObject> oldList = new List<MyObject>();
//Put some objects into oldList
List<MyObject> newList = oldList.Select(x => new MyObject(x.Param1, x.Param2)).ToList();
在此示例中,我基本上是将每个对象放在oldList中,并创建一个新的MyObject,然后将其放入newList中。