可能重复:
passing in object by ref
使用下面的代码,输出将是:
Without:
With:1
代码:
static void Main(string[] args)
{
var listWithoutRef = new List<int>();
WithoutRef(listWithoutRef);
Console.WriteLine("Without:" + string.Join(" ", listWithoutRef));
var listWithRef = new List<int>();
WithRef(ref listWithRef);
Console.WriteLine("With:" + string.Join(" ", listWithRef));
}
static void WithoutRef(List<int> inList)
{
inList = new List<int>(new int[] { 1 });
}
static void WithRef(ref List<int> inList)
{
inList = new List<int>(new int[] { 1 });
}
通过观察这个,我会说List上有一个List,所以无论如何都是由ref传递的,所以它们应该是一样的吗?我误解了ref关键字吗?或者我错过了其他什么?
答案 0 :(得分:7)
我误解了ref关键字吗?或者我错过了其他什么?
是。您没有将列表本身传递给方法,而是通过引用将引用传递给列表。这样,您就可以更改方法中的引用(List<int>
实际引用的listWithRef
),并使其反映出来。
不使用ref
关键字,您的方法无法更改对列表的引用 - 实际列表存储机制在任何一种情况下都保持不变。
请注意,如果您只想使用列表,则不需要这样做。例如,您可以在任一方法中调用List<int>.Add
,该列表将添加新项目。 Ref仅在引用类型中需要更改引用本身。
答案 1 :(得分:3)
是的,所有List
对象都以任意方式存储在堆上。但是,如果没有ref
关键字,则无法重新分配inList
参数,并使其影响调用者的范围。当您创建新的List
对象时,它会作为新对象进入堆,但除非您使用引用不会受到影响> ref 关键字。
在WithoutRef
中,如果您在现有List
上调用方法而不重新定义它,您会看到它已被修改:
inList.Clear();
inList.Add(1);