C# 将对象传递给方法,然后对该对象调用extenstion方法
昨天我在研究一个方法时遇到了一些奇怪的事情,下面是代码的简化版本:基本上问题是Bar.PopulateList方法中应用的OrderBy没有持久化C# 将对象传递给方法,然后对该对象调用extenstion方法,c#,extension-methods,linq-to-objects,byref,C#,Extension Methods,Linq To Objects,Byref,昨天我在研究一个方法时遇到了一些奇怪的事情,下面是代码的简化版本:基本上问题是Bar.PopulateList方法中应用的OrderBy没有持久化 class Foo { List MyObjects; public void PopulateMyObjects() { //Items are added to my list but the OrderBy is not persisting. Bar.PopulateList(MyO
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关键字,那么一切都会正常工作:
e、 g.公共静态int PopulateList(参考列表)
和Bar.PopulateList(参考MyObjects)
谁能启发我?我还以为物体总是通过ref传递?OrderBy是一种扩展方法,这是事实吗
谢谢,Cian试试:
return theList.OrderBy(obj => obj.ID).Count;
(我本来打算添加一个解释,但@jaredPar已经解释过了)这里的问题是,
OrderBy
调用实际上并没有以任何方式改变列表。相反,它返回一个新的IEnumerable
,它是有序的。因此,这就是为什么在方法之外看不到调用的影响,它只是不改变对象
使用OrderBy
方法创建一个新值,因此如果希望调用函数知道这个新值,则必须以某种方式返回它。最常见的位置是返回值或ref
/out
参数中
public static int PopulateList(ref List<object> theList) {
...
theList = theList.OrderBy(obj => obj.ID).ToList();
}
public static int PopulateList(参考列表){
...
theList=theList.OrderBy(obj=>obj.ID.ToList();
}
C#按值传递参数,只是引用类型的值是指向其内存位置的指针。您遇到的问题是这一行:
theList.OrderBy(obj => obj.ID);
您没有分配结果:
theList = thisList.OrderBy(obj => obj.ID).ToList();
扩展方法不会就地对文件进行排序。它返回按排序顺序返回列表元素的
使用进行就地排序。如果不使用
ref
关键字,则传递的参数是对同一对象的新引用。从某种意义上说,它是“通过引用传递的”,但你必须有点不同的想法
其他答案是正确的,OrderBy
不会就地执行,而是返回一个已排序的集合。但是,如果将参数设置为结果,则更改参数(引用)的值以指向新集合,而不是更改基础对象本身
比如说,
theList = thisList.OrderBy(obj => obj.ID).ToList();
获取列表,对其排序,然后创建一个新列表。然后将列表的值更改为指向新创建的(有序的)列表,该列表是对列表的引用。在此方法之外创建的原始引用仍然指向原始无序列表
原因是,无论何时调用
.ToList()
,实际上都会创建一个新列表。使用ref
关键字时,将包含对列表引用的实际变量传递给列表,而不是创建对同一列表的新引用。有序枚举的元素数是否与未排序列表的元素数相同?OrderBy上方有一个代码,该代码为:theList.Add(var);所以我不认为这是可以假设的。但是OrderBy不会添加或删除任何元素,所以theList.OrderBy(obj=>obj.ID).Count()
应该等于theList.Count
,不?嗨,这也是我最初的想法,但它仍然不起作用。我也这么认为,所以我尝试了:theList=thisList.OrderBy(obj=>obj.ID.ToList();正如马修在下面提到的,但这也不起作用。另外,为什么添加ref关键字会起作用?@CianM,除非theList
是out
或ref
参数,否则它仍然不起作用。否则,您只需修改方法中引用的副本。谢谢!我现在明白了,对于其他对此感到困惑的人来说,我找到了一篇很好的文章,其中有一些漂亮的图片可以提供帮助:theList=theList.OrderBy(obj=>obj.ID).ToList()的优点是什么代码>在列表排序(obj=>obj.ID)
上,谢谢。这是一个非常简洁的解释。