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

C#集合初始化器与集合定义合并使用失效问题求助

问题:Unity中C#集合初始化器在字段声明时失效的原因

首先看出现问题的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ListEX : MonoBehaviour
{
    public List<string> sList = new List<string>()
    {
        "A", "B", "C", "D",
    };


    void Start()
    {
        sList.Add("X");
        sList.Add("Y");

        string str = "";
        foreach (string i in sList)
        {
            str += i;
        }
        print(str);
    }
}

运行后输出为XY,而非预期的ABCDXY。

将初始化逻辑移到Start方法后,代码正常输出ABCDXY:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ListEX : MonoBehaviour
{
    public List<string> sList;


    void Start()
    {
        sList = new List<string>()
        {
            "A", "B", "C", "D",
        };
        sList.Add("X");
        sList.Add("Y");

        string str = "";
        foreach (string i in sList)
        {
            str += i;
        }
        print(str);
    }
}

核心原因:Unity的序列化机制

这不是C#语言本身的问题,而是Unity对MonoBehaviour子类公有字段的序列化行为导致的:

  • 当你在MonoBehaviour子类的公有字段声明处直接初始化集合(包括使用集合初始化器),Unity的序列化系统会在对象生命周期的Awake之前(具体是在反序列化阶段)重新创建该集合的实例,覆盖你在字段声明时初始化的内容。
  • 因为你没有在Inspector面板中给这个集合赋值,Unity会创建一个空的集合实例,所以Start方法中添加的"X"和"Y"就成了集合里仅有的元素,最终输出XY。
  • 而将初始化逻辑放在Start方法中时,序列化阶段已经完成,Unity不会再干预这个集合的实例,你手动创建的带初始元素的集合会被保留,后续添加的元素也能正常生效,所以输出符合预期。

补充说明

  • 不仅是List<T>,数组、Dictionary<TKey,TValue>等可序列化集合都会遇到这个问题,只要是MonoBehaviour的公有字段,且未在Inspector中赋值,Unity就会用空实例覆盖你在字段声明时的初始化。
  • 如果想要在字段声明时初始化集合且不被Unity序列化覆盖,可以给字段添加[System.NonSerialized]属性,这样Unity的序列化系统会忽略这个字段,你的初始化代码就能正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:42:26