【问题标题】:Pass List to method without modifying original list将列表传递给方法而不修改原始列表
【发布时间】:2011-10-10 12:36:22
【问题描述】:

这是将 List 传递给方法并编辑该 List 而不修改原始 List 的唯一方法吗?

class CopyTest1
{
    List<int> _myList = new List<int>();
    public CopyTest1(List<int> l)
    {
        foreach (int num in l)
        {
            _myList.Add(num);
        }
        _myList.RemoveAt(0); // no effect on original List
    }
}

【问题讨论】:

  • 这是 a 将列表传递给方法并编辑该列表而不修改原始列表的方式吗?

标签: c# list pass-by-reference


【解决方案1】:

复制列表:

_myLocalList = new List<int>(_myList);

并在本地列表上执行操作。

【讨论】:

    【解决方案2】:

    为此使用AsReadOnly

    class CopyTest1
    {
        List<int> _myList = new List<int>();
        public CopyTest1(IList<int> l)
        {
            foreach (int num in l)
            {
                _myList.Add(num);
            }
            _myList.RemoveAt(0); // no effect on original List
        }
    }
    

    并通过 CopyTest1(yourList.AsReadOnly()) 调用它。

    【讨论】:

      【解决方案3】:

      还有另一种方法。可以使用List&lt;T&gt;的拷贝构造函数:

      List<int> _myList;
      public CopyTest1(List<int> l)
      {
          _myList = new List<int>(l);
      }
      

      【讨论】:

        【解决方案4】:

        将列表中的对象克隆到其他列表并处理此副本

        static class Extensions
        {
                public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
                {
                        return listToClone.Select(item => (T)item.Clone()).ToList();
                }
        }
        

        【讨论】:

          【解决方案5】:

          当你将一个列表传递给一个方法时,你会传递一个指向所述列表的指针,这就是为什么你在你的方法中修改它时更改“原始”列表的原因。如果您想修改列表的副本,您只需制作一个。在调用 CopyTest1 的代码中,您可以根据原始列表创建一个新列表:

          public void CallsCopyTest1()
          {
              var originalList = new List<int>();
              var newList = new List<int>(originalList);
              var copyTest = new CopyTest1(newList); //Modifies newList not originalList
          }
          class CopyTest1
          {
              List<int> _myList = new List<int>();
              public CopyTest1(List<int> l)
              {
                  foreach (int num in l)
                  {
                      _myList.Add(num);
                  }
                  _myList.RemoveAt(0); // no effect on original List
              }
          }
          

          【讨论】:

          • 如果调用者忘记创建一个副本,那么他们会得到意想不到的行为——我希望类\方法来处理它
          • 这取决于类的目的是什么,是修改集合还是创建集合的副本并修改它?这个例子有点做作,我认为这不是你想要的。
          【解决方案6】:

          您可以通过引用传递对象:

          public static void ReferenceMethod(ref List<T> myParam) {
              ...
          } 
          

          编辑:问题现在已经澄清,OP 正在寻求一种不改变原始列表的方法。

          【讨论】:

          • 并且在任何情况下都没有必要将其作为ref 传递来更改原始列表-ref 允许您更改调用者范围内的引用以指向另一个对象,例如这不太可能有用
          猜你喜欢
          • 2020-01-17
          • 2016-12-09
          • 1970-01-01
          • 1970-01-01
          • 2020-11-14
          • 1970-01-01
          • 2016-03-11
          • 2016-06-09
          • 1970-01-01
          相关资源
          最近更新 更多