将集合传递给函数是否意味着函数可以更改集合的元素

本文关键字:函数 集合 元素 是否 意味着 | 更新日期: 2023-09-27 18:36:48

我实际上知道问题的答案(我认为),但我不知道原因...

所以,我知道如果我有像下面这样的课程:

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 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 + 向列表中添加一个人。我期望如果我能添加到列表中,我也可以更改元素,但我看到了不同的......

我能够将一个人添加到列表中,但无法为其中一个元素分配 null,怎么会这样?我知道列表是按值传递的,所以我不能更改列表本身(例如为其分配 null),但我可以添加到它吗?并且不能为元素分配 null?他们也被瓦尔通过了吗?

会很高兴得到一些良好而清晰的解释:)

将集合传递给函数是否意味着函数可以更改集合的元素

这是您的困惑点:

 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 时,它不会影响列表对象中的引用。引用变为 null,但私有列表引用保持不变。