将对象传递给方法,然后调用该对象的扩展方法

发布于 2024-10-05 16:40:02 字数 971 浏览 5 评论 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);

谁能启发我吗?我认为对象总是通过引用传递? 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

半寸时光 2024-10-12 16:40:03

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.

庆幸我还是我 2024-10-12 16:40:03

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

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

例如,

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

获取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,

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

takes theList, orders it and then creates a new List. Then the value of theList - 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 the ref keyword, you pass the actual variable containing the reference to the list, rather than create a new reference to the same list.

骄兵必败 2024-10-12 16:40:02

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

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

public static int PopulateList(ref List<object> theList) {
  ...
  theList = theList.OrderBy(obj => obj.ID).ToList();
}

The problem here is that the OrderBy call does not actually mutate theList in any way. It instead returns a new IEnumerable<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 a ref/out param.

public static int PopulateList(ref List<object> theList) {
  ...
  theList = theList.OrderBy(obj => obj.ID).ToList();
}
萤火眠眠 2024-10-12 16:40:02

尝试:(

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

我本来想添加一个解释,但 @jaredPar 已经解释了)

Try:

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

(I was going to add an explaination but @jaredPar has explained it)

冷了相思 2024-10-12 16:40:02

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

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

您没有分配结果:

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

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:

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

You're not assigning the result:

theList = thisList.OrderBy(obj => obj.ID).ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文