【问题标题】:List passed as reference作为参考传递的列表
【发布时间】:2015-01-25 00:09:56
【问题描述】:

由于列表是引用类型,那么为什么我在下面的示例中将任务列表计数为 0 而不是 4? 请解释这种行为

protected void AssignButton_Click(object sender, EventArgs e)
{
    List<string> membersIdList = new List<string>();
    List<Missions> missionsList = new List<Missions>();
    string selectedMembersName = SelectedMembersDetailsGet(membersIdList, missionsList); 

    //Here membersIdList count is "1" & missionsList count is "0"                      
}

private string SelectedMembersDetailsGet(List<string> membersIdList, List<Missions> missionsList)
{
    string selectedMembersName = string.Empty;
    IEnumerable<Missions> commonMissionsList = null;

    membersIdList.Add("XYZ");

    commonMissionsList = MissionsGet();  //Returns 4 records

    if (commonMissionsList != null)
    {
        missionsList = commonMissionsList.ToList(); 
    }
    return selectedMembersName;
}

【问题讨论】:

    标签: c# list ienumerable pass-by-reference


    【解决方案1】:

    引用类型按值传递。这意味着您将引用的地址传递到一个新变量中(地址被复制到一个新的内存位置,即被传递)。

    在您的子方法中,您将一个新列表重新分配给这个新的内存位置,而旧的内存位置仍然保存原始列表的地址。

    另请参阅:http://msdn.microsoft.com/en-us/library/s6938f28.aspx

    你应该做的是:

     private string SelectedMembersDetailsGet(List<string> membersIdList, List<Missions> missionsList)
     {
        string selectedMembersName = string.Empty;
        IEnumerable<Missions> commonMissionsList = null;
    
        membersIdList.Add("XYZ");
    
        commonMissionsList = MissionsGet();  //Returns 4 records
    
        if (commonMissionsList != null)
        {
            foreach(var mission in commonMissionsList)
            {
                   missionsList.Add(mission);
            }
        }
        return selectedMembersName;
    }
    

    【讨论】:

    • 我要补充一点,在 C# 中,所有参数默认都是按值传递的,而不仅仅是引用类型。
    【解决方案2】:

    要能够通过方法参数返回新列表,您必须使用 out 关键字:

    protected void AssignButton_Click(object sender, EventArgs e)
    {
        List<string> membersIdList = new List<string>();
        List<Missions> missionsList = null;
        string selectedMembersName = SelectedMembersDetailsGet(membersIdList, out missionsList); 
    
        //Here membersIdList count is "1" & missionsList count is "0"                      
    }
    
    private string SelectedMembersDetailsGet(List<string> membersIdList, out List<Missions> missionsList)
    {
        string selectedMembersName = string.Empty;
        IEnumerable<Missions> commonMissionsList = null;
    
        membersIdList.Add("XYZ");
    
        commonMissionsList = MissionsGet();  //Returns 4 records
    
        if (commonMissionsList != null)
        {
            missionsList = commonMissionsList.ToList(); 
        } 
        else 
        {
            missionList = null; // You must assign to missionList otherwise the compiler will throw an error.
        }
        return selectedMembersName;
    }
    

    out (C# Reference)

    What's the difference between the 'ref' and 'out' keywords?

    【讨论】:

    • 但@metacircle 的回答解释了为什么它的工作方式与您预期的不同。
    • 感谢您的回复,但我确实知道 ref & out 的概念,只是想知道指定的行为和“metacircle”响应几乎解释了这件事
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 2016-04-11
    • 2014-02-10
    • 1970-01-01
    • 2019-12-28
    • 2014-03-05
    • 2023-03-24
    相关资源
    最近更新 更多