Unity/C#:Dictionary存储Class值异常,切换Profile显示错误值
问题原因
你遇到的核心问题是对引用类型的工作机制理解有误。TestClass是引用类型,你在Start()里只创建了一个myTestClass实例,之后每次添加新Profile时,都是把这个同一个实例添加到字典中。字典里所有的键对应的都是内存中的同一个对象,所以最后一次修改这个实例的属性时,所有Profile显示的都会是最后一次的值——因为它们本质上指向的是同一个东西。
另外你的SetClasseValues方法逻辑也有问题:在添加新Profile时,你反而去修改当前Dropdown选中项对应的字典条目,这完全是多余且错误的操作。
解决方法
核心修复点是:每次添加新Profile时,创建一个全新的TestClass实例,而不是复用旧的。同时调整方法逻辑,确保每个Profile对应独立的实例。
修改后的代码如下:
using System.Collections.Generic; using UnityEngine; using TMPro; using UnityEngine.UI; [System.Serializable] public class TestClass { public string age; public string carColor; // 新增带参数构造函数,简化赋值 public TestClass(string age, string carColor) { this.age = age; this.carColor = carColor; } // 保留无参构造函数,兼容Unity序列化 public TestClass() { this.age = ""; this.carColor = ""; } } public class TestScript : MonoBehaviour { public TMP_InputField profileName; public TMP_InputField age; public TMP_InputField carColor; public TMP_Dropdown drop; public Button saveProfile; public Dictionary<string, TestClass> dictionary = new(); void Start() { saveProfile.onClick.AddListener(AddProfile); drop.onValueChanged.AddListener(DropdownUpdateValuesShown); } void AddProfile() { string profileKey = profileName.text.Trim(); // 过滤空名称或已存在的Profile if (string.IsNullOrEmpty(profileKey) || dictionary.ContainsKey(profileKey)) return; // 关键:创建全新的TestClass实例 TestClass newProfile = new TestClass(age.text, carColor.text); dictionary.Add(profileKey, newProfile); drop.options.Add(new TMP_Dropdown.OptionData(profileKey)); // 自动选中刚添加的Profile drop.value = drop.options.Count - 1; } void DropdownUpdateValuesShown(int index) { if (index < 0 || index >= drop.options.Count) return; string selectedKey = drop.options[index].text; // 用TryGetValue避免键不存在的报错 if (dictionary.TryGetValue(selectedKey, out TestClass selectedProfile)) { age.text = selectedProfile.age; carColor.text = selectedProfile.carColor; } } }
关键修改说明
- 移除全局的
myTestClass变量,每次添加Profile时新建TestClass实例,确保每个Profile对应独立的对象。 - 给
TestClass添加带参数构造函数,简化属性赋值操作。 - 修正
AddProfile逻辑:先校验名称合法性,再创建实例、加入字典和Dropdown,最后自动选中新选项。 - 优化
DropdownUpdateValuesShown:用TryGetValue避免字典键不存在的异常,同时增加索引合法性校验。 - 删除逻辑错误的
SetClasseValues方法,直接在创建实例时完成属性赋值。
这样修改后,每个Profile都会存储独立的TestClass实例,切换Dropdown选项时就能正确显示对应的数据了。
内容的提问来源于stack exchange,提问作者Martyx
相关产品推荐
相关产品推荐

