扩展方法在排序时不更改列表

问题描述 投票:0回答:1

我有一个公共静态类列出了我的扩展方法:

public static void OrderInts (this List<int> ints) 
{ 
    ints= ints.OrderBy(c => c).ToList(); 
} 
public static void AddInt(this List<int> ints) 
{ 
    ints.Add(34); 
} 
public static void AddIntAndOrder(this List<int> ints) 
{ 
    ints.Add(34); 
    ints = ints.OrderBy(c => c).ToList(); 
} 
public static void OrderAndAddInt(this List<int> ints) 
{
        ints = ints.OrderBy(c => c).ToList();
        ints.Add(34);
}

然后,如果我测试它们,我会注意到:

OrderInts 不会修改整数列表。

AddInt 将一个项目添加到列表中。

AddIntAndOrder 将项目添加到列表中,但不对其进行排序。

OrderAndAddInt 不会修改列表。

知道为什么会有这种奇怪的行为吗?

PS: 如果我使用静态 Util 类:

public static void ReorderInts(List<int> ints)
{
    ints = ints.OrderBy(c => c).ToList();
}  
public static void ReorderIntsByRef(ref List<int> ints)
{
    ints = ints.OrderBy(c => c).ToList();
}

那么 Util.ReorderInts(myVar) 不会更改列表,但 Util.ReorderIntsByRef(ref myVar) 会更改。

c# linq sql-order-by
1个回答
0
投票

这是预期的行为并且有充分的理由。现在你必须知道两件事:

默认情况下,C# 中的参数按值传递给函数。这意味着变量的副本被传递给该方法。

当您按值传递引用类型时:

  • 如果该方法分配参数来引用不同的对象,则调用者看不到这些更改。
  • 如果该方法修改了 > 参数引用的对象的状态,则这些更改对调用者是可见的。

来源:有关方法参数的 Microsoft 文档

你在做什么,例如在

OrderInts()
中将引用类型 (
List<T>
) 传递给方法,然后在该方法中创建一个新的 List i。 e.使用
ToList()
新建引用并将其分配给方法参数
ints

当您将参数传递给方法时,会创建该引用的副本,因此在方法内您只需为该副本分配一个新引用,函数外部的引用保持不变,仍然指向旧列表,因此没有变化从函数外部可以观察到。

要使其正常工作,您必须返回新列表,然后您可以观察新列表上的更改。

public static List<int> OrderInts(this List<int> ints)
{
    return ints.OrderBy(c => c).ToList();
}
© www.soinside.com 2019 - 2024. All rights reserved.