Class with nested struct as a property doesn't work

Why doesn't the following code work? If I change h from a property to a field, it works! Or if I change FileHeader from struct to a class it works! I am only looking for an answer to why it doesn't work.

public class MyFile
{
    public struct FileHeader
    {
        public List<string> ColNames
        {
            get;
            set;
        }

        public void setColNames()
        {
            ColNames = new List<string>();
            ColNames.Add("address");
        }
    }

    public FileHeader h
    {
        get;
        set;
    }
}

public class Program
{
    static void Main(string[] args)
    {
        MyFile o = new MyFile();
        o.h.setColNames();

        Console.WriteLine(o.h.ColNames[0]); // <- Doesn't work! No elements

        string line = System.Console.ReadLine();
    }
}
Jon Skeet
people
quotationmark

This line:

o.h.setColNames();

is equivalent to:

FileHeader tmp = o.h;
tmp.setColNames();

Because FileHeader is a struct, the value of tmp is a copy of the value of the field within o. Modifying tmp doesn't change o.h.

I would suggest:

  • You don't create custom structs unless you're creating a natural (small) value type
  • Any custom structs you do create should be immutable. At that point, it's harder to make this sort of mistake
  • Follow .NET naming conventions - a property of h and a method of setColNames are both violations of this
  • Avoid nested types unless there's a significant benefit. It's irrelevant to your actual problem here, but it can make various things trickier.

people

See more on this question at Stackoverflow