如何在不使用linq且不更改原始列表的情况下将数据复制到另一个列表

时间:2018-10-24 08:20:32

标签: c# collections copy .net-2.0

GetMaxPrice()方法中,对{{1}中的copy列表进行的更改在{{1}上被反映 }!我正在使用 .Net 2.0 ({{1}和 Linq 不可用

foreach loop

3 个答案:

答案 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;
  }
}