0

昨天我正在研究一个方法并遇到了一些奇怪的事情,这里是代码的简化版本:基本上问题是在 Bar.PopulateList 方法中应用的 OrderBy 没有持久化。


class Foo
{
    List MyObjects;

    public void PopulateMyObjects()
    {
        //Items are added to my list but the OrderBy is not persisting.
        Bar.PopulateList(MyObjects);
    }
}

class Bar
{
   public static int PopulateList(List theList)
   {
       foreach(var in WebSerbiceCall)
       {
            theList.Add(var);
       }
       // the OrderBy call only sorts 'theList' in the context of this method.
       // When I return from this method theList has been populated but the Ordering has 
       // reverted back to the order that the items were added to the list.
       theList.OrderBy(obj => obj.ID);
       return theList.Count;
   }
}

现在,如果我更新代码并按照下面添加 ref 关键字,一切正常:例如 public static int PopulateList(ref List theList) 和 Bar.PopulateList(ref MyObjects);

任何人都可以启发我吗?我认为对象总是由 ref 传递?OrderBy 是一种扩展方法吗?

谢谢, 西安

4

5 回答 5

4

这里的问题是OrderBy调用实际上并没有theList以任何方式发生变化。相反,它返回一个新IEnumerable<object>的有序的。因此,这就是为什么您在方法之外看不到调用的影响,它只是没有更改对象。

使用该OrderBy方法会创建一个新值,因此如果您希望调用函数知道这个新值,则必须以某种方式返回它。最常见的地方是在返回值或ref/out参数中。

public static int PopulateList(ref List<object> theList) {
  ...
  theList = theList.OrderBy(obj => obj.ID).ToList();
}
于 2010-12-02T00:25:41.123 回答
1

尝试:

return theList.OrderBy(obj => obj.ID).Count;

(我打算添加一个解释,但@jaredPar 已经解释过了)

于 2010-12-02T00:25:40.093 回答
1

C#按值传递参数,只是引用类型的值是指向它的内存位置的指针。您遇到的问题是这一行:

theList.OrderBy(obj => obj.ID);

您没有分配结果:

theList = thisList.OrderBy(obj => obj.ID).ToList();
于 2010-12-02T00:26:16.273 回答
1

Enumerable.OrderBy扩展方法不对List<T>就地排序。它返回一个按排序顺序返回列表元素的IEnumerable<T> 。

使用List<T>.Sort 方法List<T>进行就地排序。

于 2010-12-02T00:26:38.037 回答
0

如果您不使用ref关键字,则传递的参数是对同一对象的新引用。从某种意义上说,它是“通过引用传递”,但您必须以不同的方式思考它。

其他答案是正确的,OrderBy没有执行到位,而是返回一个有序集合。但是,如果您将参数设置为结果,那么您将更改参数(引用)的值以指向新集合,而不是更改底层对象本身。

例如,

theList = thisList.OrderBy(obj => obj.ID).ToList();

接受theList,订购它,然后创建一个新列表。然后theList- 它是对列表的引用 - 的值被更改为指向新创建的(有序)列表。在此方法之外创建的原始引用仍指向原始无序列表。

原因是每当您打电话时,.ToList()您实际上都会创建一个新列表。当您使用ref关键字时,您传递包含对列表的引用的实际变量,而不是创建对同一列表的新引用。

于 2010-12-02T00:58:13.110 回答