I have two arrays in my Base class, and I want to create Indexers that can be used in both of them, attached below is an MVCE of what I am trying to do.
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;
            }
         }
      }
In the above coed if you comment out the lines private char[] grades = new string[size]; and grades[i] = 'F'; then you can use the indexers as object_name[i] but I want to be able to access both namelist and grades by indexers.
Note : I cannot use structures to wrap them together as in my application, there size may not always be same.
Is this possible or I would need to go around with some hack.
Edit
I am looking for something like names.namelist[i] and names.grades[i], or some statements that I can access them separately. Also Indexer logic is not consistent, and even size varies in some arrays, that was skipped here to aid simplicity in MVCE.
Sorry, no-can-do.
Although Indexers can be Overloaded and can have more than one formal parameter, you can't make two variations based on the same Parameter in the same class. This is a Language Limitation (or blessing).
Indexers (C# Programming Guide)
However, this should lead you to several options.
Starting with C# 7.0, C# supports reference return values (ref returns). A reference return value allows a method to return a reference to a variable, rather than a value, back to a caller. The caller can then choose to treat the returned variable as if it were returned by value or by reference. The caller can create a new variable that is itself a reference to the returned value, called a 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";
That's to say, you could create a class that has the features you need with indexers, and make them properties of the main class. So you get something like you envisaged object.Namelist[0] and object.Grades[0].
Note : in this situation you could pass the arrays down as references and still access them in the main array like you do.
Example which includes both:
Given
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;
   }
}
Class
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];
}
Usage:
var bobo = new Bobo();
bobo.Ints[1] = 234;
bobo.DoInts(1) = 42;
                        I think only a two parameter indexer can achieve what you want.
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";
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With