0

I tried merging a collection definition with a collection initializer in C#, but failed to initialize the collection. See the codes:

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

The output of str was "XY" instead of "ABCDXY", which confuzed me a lot. The same problem happened to arrays and dictionaries when I tried them out.

I assume I made a mistake in the scope of the collection initializer. So, I tried separating the collection initializer from the collection definition.

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

The output of str was "ABCDXY", which met my expectation. My thought seems to be proved right. However, I cannot still explain the principle of how C# works with this.

I'd appreciate it if someone can give me an explanation.

3
  • Can you show the code where you create the object and call the Start() method? How do you call it anyway since it is marked as private? Maybe you call a sList.Clear() before you call Start() Commented Mar 7, 2023 at 8:16
  • @SomeBody It's Unity. Start() is a method that's there by convention, and seemingly called through reflection: docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html Commented Mar 7, 2023 at 8:18
  • I don't know Unity well, but I believe it has its very own opinion on how to initialize MonoBehaviour-derived objects. Commented Mar 7, 2023 at 8:18

1 Answer 1

0

This is a Unity MonoBehaviour script, by default public fields (sList in this question) can be edited in a window called inspector, the values of these fields will be deserialized on initial, C# has nothing todo with it, that's why you get an empty list when Start runs.

If you want to test the collection initializer and avoid being affected by serialization, you can change the access modifier to private, or use the NonSerialized attribute.

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

    [System.NonSerialized]
    public List<string> sList2 = new List<string>()
    {
        "A", "B", "C", "D",
    };
}

BTW the same problem should not happen to Dictionary<K,V> because it is not a serializable type to Unity, if there is a problem with the dictionary type, please provide the code with the problem.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the answer that is to the point! I tried coding this in a .NET console app and it worked well. As you said, C# has nothing to do with the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.