簡體   English   中英

對類 c# 中的多個數組使用索引器

[英]Using Indexers for multiple Arrays in the class c#

我的基類中有兩個數組,我想創建可以在它們兩個中使用的索引器,下面附上我正在嘗試做的 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]但我希望能夠通過索引器訪問namelistgrades

注意:我不能像在我的應用程序中那樣使用結構將它們包裝在一起,大小可能並不總是相同。

這可能嗎,或者我需要進行一些黑客攻擊。

編輯我正在尋找類似names.namelist[i]names.grades[i] ,或者一些我可以單獨訪問它們的語句。 此外,索引器邏輯不一致,甚至某些數組的大小也不同,此處跳過以幫助簡化 MVCE。

對不起,無能為力。

盡管索引器可以被重載並且可以有多個形式參數,但您不能基於同一個類中的同一個參數做出兩個變體。 這是語言限制(或祝福)。

索引器(C# 編程指南)

但是,這應該會引導您進行多種選擇。

  1. 您可以使用 C#7。 參考返回

從 C# 7.0 開始,C# 支持引用返回值(ref 返回)。 引用返回值允許方法將變量的引用而不是值返回給調用者。 然后調用者可以選擇將返回的變量視為按值或按引用返回。 調用者可以創建一個新變量,該變量本身就是對返回值的引用,稱為 ref local。

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";

  1. 您可以使用索引器制作子/嵌套類

也就是說,您可以創建一個具有索引器所需功能的類,並使它們成為主類的屬性。 所以你會得到類似於你設想的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;

我認為只有兩個參數索引器才能實現您想要的。

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";
    }
}

也許是這樣的:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM