在C#类中实现不同的索引器 [英] Implementation of different indexers within C# class

查看:172
本文介绍了在C#类中实现不同的索引器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的类中添加不同的索引器实现:

I'd like to add different indexer implementations in my class :

SpecificCollection

 public class SpecificCollection<T> : ISpecificCollection <T>
    {
        public int this[int index]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

       public object  this[int index]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

       public string  this[int index]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public event void OnAddElement;

        public event void OnRemoveElement;

        public void AddNewElement(T element)
        {
            throw new NotImplementedException();
        }

        public void DeleteElement(int index)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    }

StudentSpecificCollection

StudentSpecificCollection

 public class StudentSpecificCollection : SpecificCollection<Student>
    {

       private string[] arrName;
       private int[] arrAge;
       private object[] arrStudent ;

       public int ISpecificCollectionIndexers<Student>.this[int index]
        {
            get
            {
                return arrAge[index];
            }
            set
            {
                arrAge[index] = value;
            }
        }

        object ISpecificCollectionIndexers<Student>.this[int index]
        {
            get
            {
                return arrStudent[index];
            }
            set
            {
                arrStudent[index] = value;
            }
        }

        string ISpecificCollectionIndexers<Student>.this[int index]
        {
            get
            {
                return arrName[index];
            }
            set
            {
                arrName[index] = value;
            }
        }

        public event void OnAddElement;

        public event void OnRemoveElement;

        public void AddNewElement(Student element)
        {
            object objStudent = arrStudent.Where(x => x != null).LastOrDefault();
            int index = (objStudent == null) ? 0 : Array.IndexOf(arrStudent, objStudent);
            arrName[index] = element.Name ;
            arrAge[index] = element.Age;
            arrStudent[index] = element;
        }

        public void DeleteElement(int index)
        {
            if (index > Count - 1) return;
            arrName[index] = null;
            arrAge[index] = -1;
            arrStudent[index] = null;
        }

        public int Count
        {
            get
            {
                return arrName.Where(x=>x !=null).Count();
            }
            set
            { 
            }
        }
        public StudentSpecificCollection()
        {
            arrName = new string[100];
            arrAge = new int[100];
            arrStudent = new object[100];
        }

    }

所以我需要知道: / p>

So I need to know :


  1. 如何使用不同的索引器实现?



推荐答案

使用接口的显式实现,可以执行以下操作:

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
        {
        }
    }
}

因此实现具有相同签名的两个不同的枚举器(其中signature =类型/输入参数的数量)。注意,你可以有多个接口,每个接口有一个不同的返回类型的索引器,所以给定x接口和一个类,你可以有x + 1个不同的索引器具有相同的签名。

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.

现在...如果 Student 是一个真实类而不是对象使用隐式转换做一些技巧(你不能使用/对对象类进行隐式转换):

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);
        //}
    }
}

a MyObject 类,然后可以隐式转换为 int / string

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

然后使用

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.

这篇关于在C#类中实现不同的索引器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆