Monday, April 11, 2011

Reference Types inside a Value Type

Everybody should be clear that it is a bad idea. This is because we no longer get the "Copy Allocates new memory and therefore new values that are completely separate from the original" principal. 

However if you use an immutable reference type you can get away with it. But you should never do so simply because there really isn't any benefit from it and you might at sometime forget that it is actually a struct you are dealing with and mistakenly add a mutable reference type. 

Here is some weird sample code to show what happens when you add a reference type to a value type: 

public class MutableClass
    {
        public int SomeProperty { get; set; }
        public override string ToString()
        {
            return SomeProperty.ToString();
        }
    }
    public struct BadStruct
    {
        public string SomeProperty { get; set; }
    }
    public struct BadBadStruct
    {
        public MutableClass SomeProperty { get; set; }
    }


    class Program
    {
        static void Main(string[] args)
        {
            //BAD STRUCT
            var badStruct = new BadStruct();
            badStruct.SomeProperty = "10";
            var badStructCopy = badStruct;
            //This will actually assign a new string because they are immutable.
            badStructCopy.SomeProperty = "20"; 
            Console.WriteLine("ORIGINAL:" + badStruct.SomeProperty) ; 
            Console.WriteLine("COPY:" + badStructCopy.SomeProperty) ; 

            //BAD BAD STRUCT
            var badBadStruct = new BadBadStruct();
            badBadStruct.SomeProperty = new MutableClass() { SomeProperty = 10 };
            var badBadStructCopy = badBadStruct;
            //This will acually modify the original. 
            //Therefore the BadBadStruct no longer behaves like a value type 
            badBadStructCopy.SomeProperty.SomeProperty = 20;
            Console.WriteLine("ORIGINAL: "+badBadStruct.SomeProperty.ToString());
            Console.WriteLine("COPY: " + badBadStructCopy.SomeProperty.ToString());

        }
    }

And the output :