c#以奇怪的方式传递列表作为参数
本文关键字:列表 参数 方式传 | 更新日期: 2023-09-27 18:01:44
所以我遇到了这个bug, c#的行为就像我通过引用传递列表而不是通过值,就像它通常做的那样。我来举个例子:
using System;
using System.Collections.Generic;
namespace testprogram
{
class Program
{
static int x;
static List<Coordinate> coordinates;
static void Main(string[] args)
{
x = 10;
coordinates = new List<Coordinate>();
coordinates.Add(new Coordinate(0, 0));
coordinates.Add(new Coordinate(1, 1));
testfunction(x, coordinates);
Console.WriteLine(x);
foreach (var objekt in coordinates)
{
Console.WriteLine(objekt.xpos);
Console.WriteLine(objekt.ypos);
}
Console.Read();
}
static void testfunction(int test, List<Coordinate> objects)
{
test = 4;
foreach (Coordinate obj in objects)
{
obj.xpos = 4;
obj.ypos = 4;
}
}
}
class Coordinate
{
public int xpos;
public int ypos;
public Coordinate(int new_x, int new_y)
{
xpos = new_x;
ypos = new_y;
}
}
}
这段代码输出:
10
4
4
4
4
但是为什么呢?我期望它是:
10
0
0
1
1
我试图在函数中创建一个额外的列表,并将参数的值分配给它,但即使这样也不起作用。有什么解决办法吗?
List<T>
参数是一个引用类型,通过值传递。
如果您在方法中修改了列表中的任何项,当您离开该方法时,这些项将保持不变。
但是,如果在方法内部重新分配引用,这些更改将在方法外部丢失。如果想通过引用传递参数,可以使用ref
关键字:
static void testfunction(int test, ref List<Coordinate> objects)
{
// This will update objects outside the testfunction method
objects = new List<Coordinate>();
}
也可以使用"out
"关键字,其作用与"ref
"关键字类似。唯一的区别是,您不必在调用方法之前初始化作为out
参数传入的值,它们必须在离开方法之前初始化。
static void Main(string[] args)
{
// No need to initialise variable passed as "out" parameter
List<Coordinate> objects;
testfunction(test, out objects);
}
static void testfunction(int test, out List<Coordinate> objects)
{
// Removing this line would result in a compilation error
objects = new List<Coordinate>();
}
你的期望是错误的。列表作为值传递。这意味着名为objects
的变量是原始列表变量的值拷贝。但是列表包含引用,我的意思是列表的内容是对Coordinate
对象的引用。因此,如果您尝试更改列表变量,如objects = new List<>()
,它不会更改原始列表。但是,如果您更改列表中的对象,则更改实际上应用于原始列表。
objects[0] = new Coordinate(5, 5);
objects[0].xpos = 6;
这两个例子都改变了原来的列表。
如果你想有可能安全地改变列表中的任何东西,你必须对它进行深度克隆。您可以使用Clone()方法,但它可能比较棘手,因为您必须手动克隆列表中的每个对象。这里已经有了答案:如何创建List
您传递了对"按值"列表的引用。所以,如果你改变"testfunction"中的引用"object",那么"coordinates"将不会改变(作为指针)。但是改变"object"的元素会影响"coordinates"的元素