views:

259

answers:

3

The title may be incorrect, if so please change. I'm not sure how to ask my question so just look at the code as it should be obvious.

Using the commented code will work but I want to know why the actual code does not work. I'm sure it's wrong but how can it be fixed? Or is this not how its done?

using System;

namespace SomethingAwful.TestCases.Structs
{
    public class Program
    {
        public static void Main()
        {
            Foo f = new Foo();
            f.Bar.Baz = 1;

            Console.WriteLine(f.Bar.Baz);
        }
    }

    public class Foo
    {
        public struct FooBar
        {
            private int baz;

            public int Baz
            {
                get
                {
                    return baz;
                }
                set
                {
                    baz = value;
                }
            }

            public FooBar(int baz)
            {
                this.baz = baz;
            }
        }

        private FooBar bar;

        public FooBar Bar
        {
            get
            {
                return bar;
            }
            set
            {
                bar = value;
            }
        }

        //public FooBar Bar;

        public Foo()
        {
            this.bar = new FooBar();
            //this.Bar = new FooBar();
        }
    }
}
+7  A: 

A struct is copied only by value, so all you wind up doing is changing the copy that was returned. Use a class.

Steven Sudit
+3  A: 

Use

Foo.FooBar myFooBar = new Foo.FooBar { Baz = 1 };
f.Bar = myFooBar;

Like Steven said, you need to create an instance of a struct, and set the property to it. Otherwise it is passed by value.

Yuriy Faktorovich
That's correct. This sort of unexpected behavior is part of the argument for struct's being immutable.
Steven Sudit
+1  A: 

Also, you can think of the struct as "already allocated", so you don't need too new() it. Instead of

this.Bar = new FooBar();

Just do

this.Bar.Baz = 1;
Ray