在GetMaxPrice()
方法中,对{{1}中的copy
列表进行的更改在{{1}上被反映 }!我正在使用 .Net 2.0 ({{1}和 Linq 不可用)
foreach loop
答案 0 :(得分:2)
您可以使用Iclonable接口。您的类应实现此接口,而内部clone方法则使用memeberwise clone方法。
using System;
using System.Collections.Generic;
using System.Text;
namespace StackOverfloeProblem
{
class Program
{
static void Main(string[] args)
{
Random rnd = new Random();
List<DataPair> origialList = new List<DataPair>();
for (int indx = 0; indx < 10; indx++)
origialList.Add(new DataPair(rnd.Next(1, 100), rnd.Next(1, 100)));
GetMaxPrice(origialList);
}
static double GetMaxPrice(List<DataPair> originalList)
{
double max = 0;
//using a new list and copying using foreach does not change the behaviour
List<DataPair> copy= new List<DataPair>();
foreach (var item in originalList)
{
DataPair a = (DataPair)item.Clone();
copy.Add(a);
}
//List<DataPair> copy = originalList.Select(elt => elt.Clone()).ToList();
copy.Sort();
if (copy.Count > 0)
max = copy[originalList.Count - 1].Price;
foreach (DataPair item in copy)
item.Price = item.Volume = 0;
return max;
}
}
}
public class DataPair : IComparable<DataPair>,ICloneable
{
double _price;
double _volume;
public DataPair(double price, double volume)
{
_price = price;
_volume = volume;
}
public double Price
{
get { return _price; }
set { _price = value; }
}
public double Volume
{
get { return _volume; }
set { _volume = value; }
}
public int CompareTo(DataPair that)
{
if (this.Volume > that.Volume)
return -1;
if (this.Volume == that.Volume)
return 0;
return 1;
}
public object Clone()
{
return this.MemberwiseClone();
}
}
答案 1 :(得分:1)
您应该进行深层复制(即在原始列表中克隆每个项目):
// Not shallow copy (copy shares items with originalList)
// List<DataPair> copy = new List<DataPair>(originalList.AsReadOnly());
// But deep copy:
List<DataPair> copy = new List<DataPair>();
// copy has its own items (new DataPair...)
foreach (var item in originalList)
copy.Add(new DataPair(item.Price, item.Volume));
另一种可能性是将class
转换为struct
(因为DataPair
包含2个double
字段,因此它是struct
的不错的选择):
// Note "struct" instead of "class"
public struct DataPair : IComparable<DataPair> {
...
}
现在DataPair
将通过 value (而不是通过 reference )和
List<DataPair> copy = new List<DataPair>(originalList.AsReadOnly());
将显示深层副本。
答案 2 :(得分:1)
我会在DataPair类中创建副本构造函数,然后在GetMaxPrice函数中使用它。这将为原始列表中的每个项目创建一个新的DataPair实例,从而不会影响原始列表中的实例。
public class DataPair : IComparable<DataPair>
{
double _price;
double _volume;
public DataPair(double price, double volume)
{
_price = price;
_volume = volume;
}
public DataPair(DataPair dataPair)
{
Price = dataPair.Price;
Volume = dataPair.Volume;
}
public double Price
{
get { return _price; }
set { _price = value; }
}
public double Volume
{
get { return _volume; }
set { _volume = value; }
}
public int CompareTo(DataPair that)
{
if (this.Volume > that.Volume)
return -1;
if (this.Volume == that.Volume)
return 0;
return 1;
}
}
class Program
{
static void Main(string[] args)
{
Random rnd = new Random();
List<DataPair> origialList = new List<DataPair>();
for (int indx = 0; indx < 10; indx++)
origialList.Add(new DataPair(rnd.Next(1, 100), rnd.Next(1, 100)));
GetMaxPrice(origialList);
}
static double GetMaxPrice(List<DataPair> originalList)
{
double max = 0;
//using a new list and copying using foreach does not change the behaviour
List<DataPair> copy = new List<DataPair>();
foreach (var dataPair in originalList)
{
copy.Add(new DataPair(dataPair));
}
copy.Sort();
if (copy.Count > 0)
max = copy[originalList.Count - 1].Price;
foreach (DataPair item in copy)
item.Price = item.Volume = 0;
return max;
}
}