You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
        }
    }
}

关键修改说明

  1. 移除全局的myTestClass变量,每次添加Profile时新建TestClass实例,确保每个Profile对应独立的对象。
  2. 给TestClass添加带参数构造函数,简化属性赋值操作。
  3. 修正AddProfile逻辑:先校验名称合法性,再创建实例、加入字典和Dropdown,最后自动选中新选项。
  4. 优化DropdownUpdateValuesShown:用TryGetValue避免字典键不存在的异常,同时增加索引合法性校验。
  5. 删除逻辑错误的SetClasseValues方法,直接在创建实例时完成属性赋值。

这样修改后,每个Profile都会存储独立的TestClass实例,切换Dropdown选项时就能正确显示对应的数据了。

内容的提问来源于stack exchange,提问作者Martyx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:14:53