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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…