c#对象属性在清除Wpf控件时发生变化

本文关键字:变化 控件 Wpf 对象 属性 清除 | 更新日期: 2023-09-27 18:06:25

我有一个类,它有一个列表

public static List<bar> tempList = new List<bar>(); 
public static Foo foo = new Foo();
public class bar(){
  public string name;
  public int age;
}
public class Foo(){
  public List<bar> lBar = new List<bar>();
}

我有几个文本框控件:age1, age2在textChange上的每个控件上创建一个新对象

/*------------------------------------------------------------------
   Following code: I want runtime calculation for a logic i did with age.
                   also need to create a new object using the inputs
------------------------------------------------------------------*/
age1_textChaned(...){
     createObj( );
}
age2_textChaned(...){
     createObj( );
}
private void createObj(){
     if(tempList.Count != 0)
           tempList.Clear();
     if(age1.Text != "")
           tempList.Add(new bar("name1", Convert.ToInt32(age1.text));
     if (age2.Text != "")
           tempList.Add(new bar("name2", Convert.ToInt32(age2.text));  
}

然后我有一个按钮btn1将创建对象,然后清除文本框的内容。

btn1_Click(...){
   foo.lBar = tempList;              
   clearFields();  //here lies the question, once i clear the fields,
                   //somehow it is still affecting the values in foo.lBar; 
}
private void clearFields(){
   age1.Text = "";
   age2.Text = "";
}

所以当我输入

btn2_Click(...){
  foreach(bar b in foo.lBar){  //foo.lBar is empty i dont know why
    ...
  }
}

我在btn1_click上的当前解决方案我有这个

foreach(bar b in tempList)
    foo.lBar.Add(b);      // instead of foo.lBar = tempList      

foo.lBar = templist引起了这些变化吗?

片段只是一个完全不同项目的简单版本。

c#对象属性在清除Wpf控件时发生变化

c#中的对象是通过引用传递的,除非另有说明。

例如,下面是你正在运行的代码,以及它是如何在幕后工作的:

// create a new location in memory and refer to it using the variable tempList
public static List<bar> tempList = new List<bar>(); 
// add a new item to the list
tempList.Add(new bar("name1", Convert.ToInt32(age1.text));
// make the variable foo.lBar to also refer to the same spot in memory as tempList
foo.lBar = tempList; 
// clear the spot in memory containing the list
tempList.Clear();

最后一行同时影响tempList变量和foo.lBar变量,因为它们都引用内存中的相同位置。

避免这种情况的解决方案是在内存中创建一个对象的新副本,这样两个变量在内存中指向两个独立的实例,并且清除其中一个不会清除另一个。

这就是为什么你当前的解决方案有效

// add the memory location of each item in tempList to foo.lBar's list
foreach(bar b in tempList)
    foo.lBar.Add(b);

注意,如果你调用tempList.Clear(),它只会清除存储在tempList中的内存引用,但是实际的对象仍然存在于内存中的其他地方。

同样,如果你做了这样的事情:

tempList[0].name = "A changed name";

它也会改变foo.lBar列表中项目的name属性,因为它们在内存中共享相同的引用