将对象传递给方法,然后调用该对象的扩展方法
我昨天正在研究一个方法,遇到了一些奇怪的事情,这里是代码的简化版本: 基本上问题是 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);
谁能启发我吗?我认为对象总是通过引用传递? OrderBy 是一个扩展方法吗?
谢谢,希安
I was working on a method yesterday and ran into something strange, here is dumbed down version of the code: Basically the problem is that the OrderBy applied in the Bar.PopulateList method is not persisting.
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;
}
}
Now if I update the code and add the ref keyword as per below it all works:
e.g. public static int PopulateList(ref List theList)
and Bar.PopulateList(ref MyObjects);
Can anyone enlighten me? I thought objects were always passed by ref? Is it the fact that OrderBy is an extension method?
Thanks, Cian
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Enumerable.OrderBy 扩展方法不会对 就地列出 。它返回一个 IEnumerable ,它返回列表中的元素排序的顺序。
使用List.Sort方法 对进行排序="http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx" rel="nofollow">就地列出 。
The Enumerable.OrderBy extension method does not sort the List<T> in-place. It returns an IEnumerable<T> that returns the elements of the list in sorted order.
Use the List<T>.Sort method to sort the List<T> in-place.
如果您不使用
ref
关键字,则传递的参数是对同一对象的新引用。从某种意义上说,它是“通过引用传递”,但您必须以不同的方式思考它。其他答案是正确的,
OrderBy
不会就地执行,而是返回一个有序集合。但是,如果将参数设置为结果,那么您将更改参数的值(引用)以指向新集合,而不是更改基础对象本身。例如,
获取
theList
,对其进行排序,然后创建一个新列表。然后,theList
的值(对列表的引用)更改为指向新创建的(有序)列表。在此方法之外创建的原始引用仍然指向原始无序列表。原因是,每当您调用
.ToList()
时,您实际上都会创建一个新列表。当您使用ref
关键字时,您将传递包含对列表的引用的实际变量,而不是创建对同一列表的新引用。If you don't use the
ref
keyword then the parameter passed is a new reference to the same object. It is 'passed by reference' in a sense but you have to think about it a bit differently.Other answers are correct,
OrderBy
does not perform in place and instead returns an ordered collection. But if you set your parameter to the result, then you change the value of the parameter (the reference) to point to the new collection, rather than changing the underlying object itself.For example,
takes
theList
, orders it and then creates a new List. Then the value oftheList
- which is a reference to a list - is changed to point to the newly created (ordered) list. The original reference, created outside this method, still points to the original unordered list.The reason is that whenever you call
.ToList()
you actually create a new list. When you use theref
keyword, you pass the actual variable containing the reference to the list, rather than create a new reference to the same list.这里的问题是
OrderBy
调用实际上并没有以任何方式改变theList
。相反,它返回一个新的已排序的IEnumerable
使用
OrderBy
方法创建一个新值,因此如果您希望调用函数知道这个新值,则必须以某种方式返回它。最常见的位置是返回值或ref
/out
参数。The problem here is that the
OrderBy
call does not actually mutatetheList
in any way. It instead returns a newIEnumerable<object>
which is ordered. Hence this is why you do not see the affects of the call outside the method, it's simply not changing the object.Using the
OrderBy
method creates a new value and hence if you want the calling function to be aware of this new value it must be returned in some manner. The most common places are in the return value or in aref
/out
param.尝试:(
我本来想添加一个解释,但 @jaredPar 已经解释了)
Try:
(I was going to add an explaination but @jaredPar has explained it)
C# 按值传递参数,只是引用类型的值是指向其内存位置的指针。您遇到的问题是这一行:
您没有分配结果:
C# passes arguments by value, it's just that the value of a reference type is the pointer to it's memory location. The problem you are having is this line:
You're not assigning the result: