[Solved] Implementation of different indexers within C# class


Using explicit implementation of interfaces, you can do something like:

public interface IMyClass
{
    object this[int index]
    {
        get; set;
    }
}

public class MyClass : IMyClass
{
    public string this[int index]
    {
        get
        {
            return "";
        }

        set
        {
        }
    }

    object IMyClass.this[int index]
    {
        get
        {
            return "";
        }

        set
        {
        }
    }
}

so implement two different enumerators with the same signature (where signature = type/number of input parameters). Note that you can have multiple interfaces, each one with an indexer with a different return type, so given x interfaces and one class, you can have x + 1 distinct indexers with the same signature.

Now… If Student was a “real” class instead of an object, you could do some tricks with implicit casts (you can’t do implicit casts with/against the object class):

public class StudentSpecificCollection
{
    private string[] arrName;
    private int[] arrAge;
    private object[] arrStudent;

    public MyObject this[int index]
    {
        get
        {
            return new MyObject(this, index);
        }

        set
        {
            if (value.Type.HasFlag(MyObject.MyObjectType.Name))
            {
                arrName[index] = value;
            }

            if (value.Type.HasFlag(MyObject.MyObjectType.Age))
            {
                arrAge[index] = value;
            }

            if (value.Type.HasFlag(MyObject.MyObjectType.Student))
            {
                arrStudent[index] = value;
            }
        }
    }

    public class MyObject
    {
        [Flags]
        public enum MyObjectType
        {
            Name = 1,
            Age = 2,
            Student = 4
        }

        public readonly MyObjectType Type;
        public readonly string Name;
        public readonly int Age;
        public readonly object Student;

        protected MyObject(string name)
        {
            Type = MyObjectType.Name;
            Name = name;
        }

        protected MyObject(int age)
        {
            Type = MyObjectType.Age;
            Age = age;
        }

        protected MyObject(object student)
        {
            Type = MyObjectType.Student;
            Student = student;
        }

        public MyObject(StudentSpecificCollection obj, int ix)
        {
            Name = obj.arrName[ix];
            Age = obj.arrAge[ix];
            Student = obj.arrStudent[ix];
        }

        public static implicit operator string(MyObject obj)
        {
            if (!obj.Type.HasFlag(MyObjectType.Name))
            {
                throw new Exception();
            }

            return obj.Name;
        }

        public static implicit operator int(MyObject obj)
        {
            if (!obj.Type.HasFlag(MyObjectType.Age))
            {
                throw new Exception();
            }

            return obj.Age;
        }

        //public static implicit operator object(MyObject obj)
        //{
        //    if (!obj.Type.HasFlag(MyObjectType.Student))
        //    {
        //        throw new Exception();
        //    }

        //    return obj.Student;
        //}

        public static implicit operator MyObject(string name)
        {
            return new MyObject(name);
        }

        public static implicit operator MyObject(int age)
        {
            return new MyObject(age);
        }

        //public static implicit operator MyObject(object student)
        //{
        //    return new MyObject(student);
        //}
    }
}

(the indexer returns a MyObject class that then can be implicitly casted to int/string)

then use as

var obj = new StudentSpecificCollection();
// Load some students here
obj[0] = "Foo";
obj[0] = 25;
string name = obj[0];
int age = obj[0];

Note that I don’t think this is a good idea. But you asked for it.

4

solved Implementation of different indexers within C# class