在 c# 中,发送到方法的所有参数都按值传递,除非它们使用ref 或out 关键字传递。
这包括值类型、引用类型、可变和不可变类型的参数。
当将引用类型参数传递给方法时,实际发生的是参数的引用按值传递.
这意味着该方法实际上持有一个对传递给它的参数的新引用。
因此,当使用方法外部的引用时,对该参数状态的任何更改也会反映出来。
但是,当为方法内部的引用分配新值时,它不会反映在方法外部的引用上。
要获得更好、更广泛的解释,请阅读 Jon Skeet 的 Parameter passing in C# 文章。
您无法使用任何 不可变 类型对此进行测试,因为根据定义,不可变类型无法更改。
但是,您可以使用任何可变类型对此进行测试:
public static void Main()
{
var x = new List<int>();
x.Add(1);
Add(x, 2);
Console.WriteLine(x.Count.ToString()); // will print "2";
AddRef(ref x, 3);
Console.WriteLine(x.Count.ToString()); // will print "1";
Add3(x, 1, 2, 3 );
Console.WriteLine(x.Count.ToString()); // will also print "1";
Add3Ref(ref x, 1, 2, 3 );
Console.WriteLine(x.Count.ToString()); // will print "3";
}
static void Add(List<int> list, int value)
{
// adding an item to the list, thus chaning the state of the list.
// this will reflect on the list sent to the method,
// since a List is a reference type.
list.Add(value);
}
static void AddRef(ref List<int> list, int value)
{
list = new List<int>(); // same as the s += “Hi”; in the question
// Adding the value to the list.
// Note that this change will reflect on the list passed to the method,
// since it is passed using the ref keyword.
list.Add(value);
}
static void Add3(List<int> list, int value1, int value2, int value3)
{
list = new List<int>(); // same as the s += “Hi”; in the question
// these values are added to the new list.
// since the reference to the list was passed by value,
// it WILL NOT effect the list sent to the method.
list.Add(value1);
list.Add(value2);
list.Add(value3);
}
static void Add3Ref(ref List<int> list, int value1, int value2, int value3)
{
list = new List<int>(); // same as the s += “Hi”; in the question
// these values are added to the new list.
// since the list was passed by reference,
// it WILL effect the list sent to the method.
list.Add(value1);
list.Add(value2);
list.Add(value3);
}
You can see for yourself on this fiddle.