昨天我正在研究一种方法并遇到一些奇怪的问题,这里是代码版本的愚蠢:基本上问题是在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是一种扩展方法吗?
谢谢,Cian
答案 0 :(得分:4)
这里的问题是OrderBy
调用实际上并没有以任何方式改变theList
。它改为返回一个新的IEnumerable<object>
,它是有序的。因此,这就是为什么你没有看到方法之外的调用的影响,它只是不改变对象。
使用OrderBy
方法创建一个新值,因此如果您希望调用函数知道这个新值,则必须以某种方式返回它。最常见的地方是返回值或ref
/ out
参数。
public static int PopulateList(ref List<object> theList) {
...
theList = theList.OrderBy(obj => obj.ID).ToList();
}
答案 1 :(得分:1)
尝试:
return theList.OrderBy(obj => obj.ID).Count;
(我打算补充说明,但是@jaredPar解释了它)
答案 2 :(得分:1)
C#按值传递参数,只是引用类型的值是指向它的内存位置的指针。你遇到的问题是这一行:
theList.OrderBy(obj => obj.ID);
您没有分配结果:
theList = thisList.OrderBy(obj => obj.ID).ToList();
答案 3 :(得分:1)
Enumerable.OrderBy扩展方法未对就地List<T>进行排序。它返回一个IEnumerable<T>,它按排序顺序返回列表的元素。
使用List<T>.Sort method对就地List<T>进行排序。
答案 4 :(得分:0)
如果不使用ref
关键字,则传递的参数是对同一对象的新引用。在某种意义上它是“通过引用传递”,但你必须对它有所不同。
其他答案都是正确的,OrderBy
没有执行,而是返回有序集合。但是,如果将参数设置为结果,则将参数(引用)的值更改为指向新集合,而不是更改基础对象本身。
例如,
theList = thisList.OrderBy(obj => obj.ID).ToList();
获取theList
,对其进行排序,然后创建一个新的List。然后,theList
的值 - 它是对列表的引用 - 被更改为指向新创建的(有序)列表。在此方法之外创建的原始引用仍指向原始无序列表。
原因是无论何时拨打.ToList()
,您实际上都会创建一个新列表。当您使用ref
关键字时,将传递包含对列表的引用的实际变量,而不是创建对同一列表的新引用。