首先是总结:
1.List传值是引用传递
2.使用OrderBy返回值赋值会改变被赋值变量的指针(重新分配空间)
事情是这样的:
我有一个需求(WPF),从外部导入fsa格式文件,导入完成后通过list更新DataGrid数据源,因后续需要用到该列表,发现对列表的排序失效了?(在封装好的方法中实现)以下是部分代码:
定义List:
public List<FragmentAnalysisModel> fsaFiles = new List<FragmentAnalysisModel>();
增加初始化数据源:
private void InitSampleViewDataSource(List<FragmentAnalysisModel> modelList)
...
//重新排序
if (modelList.Count > 0)
modelList = modelList.OrderBy(t=>t.SampleFileName).ToList<FragmentAnalysisModel>();
...
//其他逻辑
本觉得此时的fsaFiles 应当已经是排序过后的列表,结果却是在InitSampleViewDataSource方法外部的fsaFiles未排序,在其内部的modelList实现了排序。那么问题出在哪里呢?看一个例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test.Math
{
class Program
{
static void Main(string[] args)
{
Execute(list);
}
public static List<Student> list = new List<Student>() {
new Student() { StuID = 6, Name = "小明" },
new Student() { StuID = 5, Name = "小王" },
new Student() { StuID = 3, Name = "小马" },
new Student() { StuID = 1, Name = "小钱" },
new Student() { StuID = 4, Name = "小白" },
new Student() { StuID = 2, Name = "小黄" },
new Student() { StuID = 7, Name = "小黑" }
};
public static void Execute(List<Student> _list)
{
Console.Write("原列表信息:");
foreach (Student item in _list)
{
Console.Write(item.StuID + " ");
}
Console.WriteLine();
OrderList(_list);
Console.Write("调用OrderList后原列表信息:");
foreach (Student item in _list)
{
Console.Write(item.StuID + " ");
}
Console.WriteLine();
_list = _list.OrderBy(s => s.StuID).ToList<Student>();
Console.Write("不调用OrderList排序的列表信息:");
foreach (Student item in _list)
{
Console.Write(item.StuID + " ");
}
Console.Read();
}
private static void OrderList(List<Student> _list)
{
_list.Add(new Student() { StuID = 8, Name = "小紫" });
_list = _list.OrderBy(s => s.StuID).ToList<Student>();
_list.Add(new Student() { StuID = 9, Name = "小兰" });
Console.Write("引用传参排序显示:");
foreach (Student item in _list)
{
Console.Write(item.StuID + " ");
}
Console.WriteLine();
}
public class Student
{
public int StuID;
public string Name;
}
}
}
输出结果是:
OK,与期望的不同?问题出在这:
_list.Add(new Student() { StuID = 8, Name = "小紫" });
_list = _list.OrderBy(s => s.StuID).ToList<Student>();
_list.Add(new Student() { StuID = 9, Name = "小兰" });
list是引用传递没错,但是上述代码的中间一行对_list进行了赋值操作,系统为OrderBy后返回的List分配了新的内存空间,当前局部变量_list的指针不再指向list的值。那么后续对_list的操作都不再改变list,但是排序赋值前对list的改变仍然会奏效。
因此应该在哪里对list进行排序也清晰明了了。