分配后列表意外清除[重复]

Posted

技术标签:

【中文标题】分配后列表意外清除[重复]【英文标题】:Lists getting cleared unexpectedly after assignment [duplicate] 【发布时间】:2019-05-12 12:13:33 【问题描述】:
class ListHolder

    public List<char> List;
    public ListHolder(List<char> l)
    
        this.List = l;
    


class Program

    static void Main(string[] args)
    
        List<char> a = new List<char>();
        a.Add('s');
        ListHolder c = new ListHolder(a);
        a.Clear();
        Console.WriteLine(c.List.Count);
    

我已经在该类中添加了一些列表,然后我清除了列表并在类中写入了列表的计数...我希望输出应该是“1”(因为类中的列表包含字母's'),而是写“0”。怎么可能, a.Clear 甚至清除了班级中的列表?如何实现只清除 Main 中的列表和类中的列表?

【问题讨论】:

正确,您将 REFERENCE 传递给列表。 因为参考和价值(阅读这个:***.com/questions/23107941/…) c 不包含新列表,它包含对原始列表a 的引用,因此在a 上调用Clear 也会清除cl 中的列表,因为它们是同样的事情 当您通过任何变量更新列表时引用它,此更改将反映在所有引用中。 我建议你阅读reference types 【参考方案1】:

由于您传递的是引用而不是列表本身,因此您将在清除列表后得到 0。

你要做的就是向类传递一个新的List,其中包含另一个列表的值:

cl c = new cl(new List<char>(a)); 

这样,即使您清除了“主”列表,在您的班级中,您的项目数也会为 1。

希望这会有所帮助。

【讨论】:

【参考方案2】:

列表和其他类是引用类型。简而言之,这意味着您在内存中的某处有一个对象,并且上面有一个引用。

this.l = l; 表示您将对第一个列表的引用复制到类字段。所以你有一个列表和两个引用。当您通过a 变量清除列表时,无论您在清除后如何处理它 - 通过acl.l。您的单个列表已被清除。

如果你想避免这种情况,你需要在你的构造函数中创建一个 list 的副本:

public cl(List<char> l)
    
        this.l = new List<char>();
        this.l.AddRange(l);
    

我建议您阅读有关引用类型的更多信息。它们被广泛使用,有关它们的知识将为您提供良好的编程技能基础。

【讨论】:

【参考方案3】:
 if (a is System.ValueType)
 
   //never
    Console.WriteLine("List is value type");
 
 if ('s' is System.ValueType)
 
     //always
     Console.WriteLine("char is value type");
 

我想你知道,char 是值类型,而 list 是引用类型。

即使是这样的代码;它会是一样的。

List<char> a = new List<char>();
a.Add('s');
List<char> c = a;
a.Clear();
Console.WriteLine(c.Count);

【讨论】:

以上是关于分配后列表意外清除[重复]的主要内容,如果未能解决你的问题,请参考以下文章

分配后列表意外更改。为啥会这样,我该如何预防?

清除 R 会话分配的内存(gc()没有帮助!)[重复]

但是,虽然后来将明文密码分配给密码,但此变量永远不会从内存中清除 [重复]

安全清除内存并重新分配

如何清除 xcassets 未分配子项的警告?

单击时如何清除editText中的字符串[重复]