Saturday, August 30, 2014

Completely Read-Only Object as Return Value

NOTE: I am not proposing a 'secure' code. It's just to make your code dumb proof, not hack proof.
At the pinnacle of the insanity, when you have that bong affecting your normal senses, you may want to return that object from your beloved method which cannot be modified in anyway. You cannot even create a new object of the class that you are returning to have exclusive access to your return type. Anyways, whatever it can be used (?) for, it's here:
using System;
using System.Collections.ObjectModel;
using System.Security.Permissions;

public class ReadOnlyClassAsReturnValue
{
    private int sampleInt;
    // make regular property read-only by creating only 'get' call 
    public int SampleInt
    {
        get { return sampleInt; }
    }

    private bool[] sampleCollection;
    // Collections need to be made ReadOnlyCollection<T> . 
    //      NOTE: Though ReadOnlyCollection<T> can be casted as IList<T>, never 
    //          do that. It allows someone to to change collection in compilte
    //          time only to realized during runtime that it cannot be changed
    public ReadOnlyCollection<bool> SampleCollection
    {
        get { return Array.AsReadOnly(sampleCollection); } //gives ReadOnlyCollection<T>
    }

    // 'private' varialbes can only be assigned in contructor. If any variable need to be assigned after
    // object is created, it need to be made 'internal'.
    protected string sampleString = "x";
    public string SampleString
    {
        get { return sampleString; }
    }

    // Contructor is made 'protected' as this class is to be used by serious consumers only.
    // If ultimate (dumb) user is going to be outside your assembly, you can make it 
    // 'internal' instead of 'prorected' eliminating need to override this class and 
    // providing more protection than 'protected' (and 'proected internal').
    protected ReadOnlyClassAsReturnValue(int sampleInt, bool[] sampleCollection)
    {
        this.sampleInt = sampleInt;
        this.sampleCollection = sampleCollection;
    }
}

public class PrimaryUserClass
{
    // Inherit ReadOnlyClassAsReturnValue so internal methods/properties/variables can be assigned
    private class ReadOnlyObjectMaker : ReadOnlyClassAsReturnValue
    {
        public ReadOnlyObjectMaker(int sampleInt, bool[] sampleCollection)
            : base(sampleInt, sampleCollection)
        { }

        public string SampleString
        {
            set
            {
                this.sampleString = value;
            }
        }
    }

    //NO ONE CAN CHANGE THIS RETURN VALUE
    public ReadOnlyClassAsReturnValue ReadOnlyClassReturner()
    {
        ReadOnlyObjectMaker returnValue = new ReadOnlyObjectMaker(10, new bool[] { true, false });
        returnValue.SampleString = "I can assign this";
        return returnValue;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var returnValue = new PrimaryUserClass().ReadOnlyClassReturner();
        //returnValue cannot be modified. Why? Just for fun. Someone has to hack it to change anythingin returnValue.
    }
}