将集合传递给函数是否意味着该函数可以更改集合的元素?
does passing a collection to a function means the function can change the collection's elements?
其实我知道问题的答案(我想)但我不知道原因...
所以,我知道如果我有一个像下面这样的 class:
class Man
{
public string Name;
public int Height;
public Man() { }
public Man(string i_name, int i_height)
{
Name = i_name;
Height = i_height;
}
}
我有以下程序class(具有主要功能):
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Man g = new Man("greg", 175);
//assigning null to g inside the function.
p.ChangeMan(g);
Console.WriteLine(g == null? "the function changed g out side the function" : "the function did not change g out side the function");
//the output of course is that the function did not change g outside the function.
//now I am creating a list of Man and adding 5 Man instances to it.
List<Man> manList = new List<Man>();
for (int i = 0; i < 5; i++)
{
manList.Add(new Man("Gadi" + i.ToString(), 10 * i));
}
//assigning null to the list insdie the function
p.ChangeList(manList);
Console.WriteLine(manList == null ? "the function changed the list out side the function" : "the function did not change the list out side the function");
//the output of cousre again is the function did not change the list out side the function
//now comes the part I dont understand...
p.ChangeManInAList(manList);
Console.WriteLine("list count = " + manList.Count());
//count is now 6.
Console.WriteLine(manList[0] == null ? "the function changed the element out side the function" : "the function did not change the element out side the function");
//the out again - the function did not change...
}
public void ChangeMan(Man g)
{
g = null;
}
public void ChangeManInAList(IList<Man> gadiList)
{
Man g = gadiList.First<Man>();
g = null;
Console.WriteLine(g == null? "g is null" : "g is not null");
gadiList.Add(new Man("a new gadi", 200));
Console.WriteLine("list count = " + gadiList.Count());
}
public void ChangeList(List<Man> list)
{
list = null;
}
}
我将 null 分配给列表的第一个元素 + 向列表添加一个 Man。我以为如果我可以添加到列表中,我也可以更改元素,但是我看到了不同...
我能够将一个 Man 添加到列表中,但无法将 null 分配给其中一个元素,这是怎么回事?我知道列表是按值传递的,所以我不能更改列表本身(比如为它分配 null),但我可以添加它吗?并且不能将 null 分配给元素?它们也被 val 传递了吗?
会很高兴得到一些好的和清晰的解释:)
这是你的困惑点:
Man g = gadiList.First<Man>();
g = null;
你实际上做的是从列表中获取 Man
并将其分配给局部变量 g
.
然后,您将不同的值分配给变量 g
.
在这里您没有更改列表任何成员的值,您只是更改了变量 g
所指的值。
让我们尝试将其与此示例进行比较:
int a = 5;
int b = a;
b = 3;
//you wouldn't expect `a` to be 3 now, would you?
要更改列表项的值,您需要将列表索引显式设置为不同的值:
Man g = gadiList.First<Man>();
gadiList[gadiList.IndexOf(g)] = null;
//or specifically in this case:
gadiList[0] = null;
当您从列表中获取元素时,您将获得对列表项的新引用。
因此,您得到两个引用:一个(列表对象中的私有引用),您的引用。
当您将引用设置为 null 时,它不会影响列表对象中的引用。您的引用变为空,但私有列表引用保持不变。
其实我知道问题的答案(我想)但我不知道原因...
所以,我知道如果我有一个像下面这样的 class:
class Man
{
public string Name;
public int Height;
public Man() { }
public Man(string i_name, int i_height)
{
Name = i_name;
Height = i_height;
}
}
我有以下程序class(具有主要功能):
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Man g = new Man("greg", 175);
//assigning null to g inside the function.
p.ChangeMan(g);
Console.WriteLine(g == null? "the function changed g out side the function" : "the function did not change g out side the function");
//the output of course is that the function did not change g outside the function.
//now I am creating a list of Man and adding 5 Man instances to it.
List<Man> manList = new List<Man>();
for (int i = 0; i < 5; i++)
{
manList.Add(new Man("Gadi" + i.ToString(), 10 * i));
}
//assigning null to the list insdie the function
p.ChangeList(manList);
Console.WriteLine(manList == null ? "the function changed the list out side the function" : "the function did not change the list out side the function");
//the output of cousre again is the function did not change the list out side the function
//now comes the part I dont understand...
p.ChangeManInAList(manList);
Console.WriteLine("list count = " + manList.Count());
//count is now 6.
Console.WriteLine(manList[0] == null ? "the function changed the element out side the function" : "the function did not change the element out side the function");
//the out again - the function did not change...
}
public void ChangeMan(Man g)
{
g = null;
}
public void ChangeManInAList(IList<Man> gadiList)
{
Man g = gadiList.First<Man>();
g = null;
Console.WriteLine(g == null? "g is null" : "g is not null");
gadiList.Add(new Man("a new gadi", 200));
Console.WriteLine("list count = " + gadiList.Count());
}
public void ChangeList(List<Man> list)
{
list = null;
}
}
我将 null 分配给列表的第一个元素 + 向列表添加一个 Man。我以为如果我可以添加到列表中,我也可以更改元素,但是我看到了不同...
我能够将一个 Man 添加到列表中,但无法将 null 分配给其中一个元素,这是怎么回事?我知道列表是按值传递的,所以我不能更改列表本身(比如为它分配 null),但我可以添加它吗?并且不能将 null 分配给元素?它们也被 val 传递了吗?
会很高兴得到一些好的和清晰的解释:)
这是你的困惑点:
Man g = gadiList.First<Man>();
g = null;
你实际上做的是从列表中获取 Man
并将其分配给局部变量 g
.
然后,您将不同的值分配给变量 g
.
在这里您没有更改列表任何成员的值,您只是更改了变量 g
所指的值。
让我们尝试将其与此示例进行比较:
int a = 5;
int b = a;
b = 3;
//you wouldn't expect `a` to be 3 now, would you?
要更改列表项的值,您需要将列表索引显式设置为不同的值:
Man g = gadiList.First<Man>();
gadiList[gadiList.IndexOf(g)] = null;
//or specifically in this case:
gadiList[0] = null;
当您从列表中获取元素时,您将获得对列表项的新引用。 因此,您得到两个引用:一个(列表对象中的私有引用),您的引用。 当您将引用设置为 null 时,它不会影响列表对象中的引用。您的引用变为空,但私有列表引用保持不变。