代码之家  ›  专栏  ›  技术社区  ›  anand_v.singh

对c类中的多个数组使用索引器#

c#
  •  0
  • anand_v.singh  · 技术社区  · 7 年前

    我的基类中有两个数组,我想创建可以在这两个数组中使用的索引器,下面是我尝试做的MVCE。

    class Indexer
          {
          private string[] namelist = new string[size];
          private char[] grades = new string[size];
          static public int size = 10;
    
          public IndexedNames() {
             for (int i = 0; i < size; i++){
                namelist[i] = "N. A.";
                grades[i] = 'F';
             }
          }
          public string this[int index] {
             get {
                string tmp;
    
                if( index >= 0 && index <= size-1 ) {
                   tmp = namelist[index];
                } else {
                   tmp = "";
                }
    
                return ( tmp );
             }
             set {
                if( index >= 0 && index <= size-1 ) {
                   namelist[index] = value;
                }
             }
          }
    
    

    在上面的coed中,如果你注释掉了行 private char[] grades = new string[size]; grades[i] = 'F'; 然后您可以将索引器用作 object_name[i] namelist 和 grades 通过索引器。

    注

    这是可能的,否则我就需要找些黑客。

    我在找像这样的东西 names.namelist[i] 和 names.grades[i] ,或一些我可以单独访问的语句。此外,索引器逻辑也不一致,甚至在某些数组中大小也不同,这里跳过了这一点,以帮助简化MVCE。

    2 回复  |  直到 7 年前
        1
  •  4
  •   halfer Jatin Pandey    5 年前

    对不起,不行。

    索引器 超载 在同一个班。这是一个 语言限制 (或祝福)。

    Indexers (C# Programming Guide)

    然而,这将引导您选择几个选项。

    1. Ref returns

    从C#7.0开始,C#支持参考返回值(参考 返回)。引用返回值允许方法返回 然后,调用方可以选择将返回的变量视为 变量本身是对返回值的引用,称为 参考本地。

    public ref string Namelist(int position)
    {
    
         if (array == null)
             throw new ArgumentNullException(nameof(array));
    
         if (position < 0 || position >= array.Length)
             throw new ArgumentOutOfRangeException(nameof(position));
    
         return ref array[position];
    }
    
    ...
    
    // Which allows you to do funky things like this, etc.
    
    object.NameList(1) = "bob";
    
    

    也就是说,您可以创建一个具有索引器所需功能的类,并使其成为主类的属性。所以你得到了你想象的东西 object.Namelist[0] 和 object.Grades[0]

    注 :在这种情况下,您可以将数组作为引用向下传递,并且仍然可以像您一样在主数组中访问它们。


    示例包括以下两个方面:

    鉴于

    public class GenericIndexer<T>
    {
       private T[] _array;
    
       public GenericIndexer(T[] array)
       {
          _array = array;
       }
       public T this[int i]
       {
          get => _array[i];
          set => _array[i] = value;
       }
    }
    

    public class Bobo
    {
       private int[] _ints = { 2, 3, 4, 5, 5 };
       private string[] _strings = { "asd","asdd","sdf" };
    
       public Bobo()
       {
    
          Strings = new GenericIndexer<string>(_strings);
          Ints = new GenericIndexer<int>(_ints);
       }
       public GenericIndexer<string> Strings ;
       public GenericIndexer<int> Ints ;
    
       public void Test()
       {
          _ints[0] = 234;
       }
    
       public ref int DoInts(int pos)  => ref _ints[pos];
       public ref string DoStrings(int pos)  => ref _strings[pos];
    }
    

    用法:

    var bobo = new Bobo();
    bobo.Ints[1] = 234;
    bobo.DoInts(1) = 42;
    
        2
  •  2
  •   Alex.Wei    7 年前

    我认为只有两个参数的索引器才能实现您想要的。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    
    namespace ConsoleApp1
    {
        class MyClass
        {
            protected static Dictionary<string, FieldInfo[]> table = new Dictionary<string, FieldInfo[]>();
            static public int size = 10;
    
            protected char[] grades = new char[size];
    
            public object this[string name, int index]
            {
                get
                {
                    var fieldInfos = table[this.GetType().FullName];
                    return ((Array)fieldInfos.First((x) => x.Name == name).GetValue(this)).GetValue(index);
                }
                set
                {
                    var fieldInfos = table[this.GetType().FullName];
                    ((Array)fieldInfos.First((x) => x.Name == name).GetValue(this)).SetValue(value, index);
                }
            }
    
            static void Main()
            {
                var names = new MyChildClass();
                names[DataColumns.Grades, 1] = 'S';
                names[DataColumns.NameList, 9] = "W.S";
            }
        }
    
        class MyChildClass : MyClass
        {
            private string[] namelist = new string[size];
    
            static MyChildClass()
            {
                var t = typeof(MyChildClass);
                table.Add(t.FullName, t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance));
            }
    
            public MyChildClass()
            {
                for (int i = 0; i < size; i++)
                {
                    namelist[i] = "N. A.";
                    grades[i] = 'F';
                }
            }
        }
    
        static class DataColumns
        {
            public static string NameList = "namelist";
            public static string Grades = "grades";
        }
    }
    
        3
  •  1
  •   Gauravsa    7 年前

    class Indexer
    {
        private string[] namelist = new string[size];
        private string[] grades = new string[size + 1]; // size +1 to indicate different 
        // size
        static public int size = 10;
    
        public void IndexedNames()
        {
            for (int i = 0; i < size; i++)
            {
                namelist[i] = "N. A.";
                grades[i] = "F";
            }
        }
    
        public string this[int i, int j]
        {
            get
            {
                string tmp;
    
                // we need to return first array
                if (i > 0)
                {
                    tmp = namelist[i];
                }
                else
                {
                    tmp = grades[i];
                }
    
                return (tmp);
            }
            set
            {
                if (i > 0)
                {
                    namelist[i] = value;
                }
                else grades[i] = value;
            }
        }
    }