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

How to copy data to another list without linq and without altering the original list

GetMaxPrice()方法中,foreach loop中的copy列表所做的更改反映originalList 上!我正在使用 .Net 2.0ToList()Linq 不可用

public class DataPair : IComparable<DataPair> 
{
    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;
    }

}
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>(originalList.AsReadOnly()); 
        copy.Sort();
        if (copy.Count > 0)
            max = copy[originalList.Count - 1].Price;

        foreach (DataPair item in copy)
            item.Price = item.Volume = 0;

        return max;
    }
}

你应该深度复制(即克隆原始列表中的每个项目):

// 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()); 

会出现深拷贝。

我会在 DataPair class 中创建复制构造函数,然后在 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;
  }
}

你可以使用 Icloneable interface.Your class 应该实现这个接口并且在克隆方法内部使用 memberwiseclone 方法。

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();  
    }
}