3

I am trying to figure out if it's possible to pass an object as the index value for a multidimensional array.

var nums = new int[3,3];
// of course you can index by literal integers
nums[0, 2] = 99;
// but can you index by an array?  This does not work
var index = new [] {0, 2};
nums[index] = 100;

// I can use GetValue with the int array, but this returns an object not an int
nums.GetValue(new [] {0, 2});

So does anyone know what type I should be passing to the multidimensional array indexer to satisfy the compiler?

4 Answers 4

3

The short answer is no, you cannot do this natively.

The slightly longer answer is yes, you can implement such behavior using extension methods. You can add an extension method that would apply to all arrays like so:

public static class ArrayExtender
{
    public static T GetValue<T>(this T[,] array, params int[] indices)
    {
        return (T)array.GetValue(indices);
    }

    public static void SetValue<T>(this T[,] array, T value, params int[] indices)
    {
        array.SetValue(value, indices);
    }

    public static T ExchangeValue<T>(this T[,] array, T value, params int[] indices)
    {
        var previousValue = GetValue(array, indices);
        array.SetValue(value, indices);

        return previousValue;
    }
}

With that you can use:

        var matrix = new int[3, 3];
        matrix[0, 2] = 99;

        var oldValue = matrix.GetValue(0, 2);
        matrix.SetValue(100, 0, 2);
        var newValue = matrix.GetValue(0, 2);

        Console.WriteLine("Old Value = {0}", oldValue);
        Console.WriteLine("New Value = {0}", newValue);

Output:

Old Value = 99
New Value = 100

In most cases there is an object-oriented answer to why you need this functionality and proper custom classes can be created to facilitate this. For example, I may have a chessboard that I create several classes with helper methods:

class GameBoard
{
  public GamePiece GetPieceAtLocation(Point location) { ... }
}
Sign up to request clarification or add additional context in comments.

1 Comment

As you point out there is indeed a good OO solution. I will just add the indexer to my custom class as you suggest and have it accept my Point class as the index.
1

No, you cannot do this. Array indexers are syntactical, they are not "virtual" arrays. That means it expects a series of expressions separated by a comma, not an expression that might represent an array.

Similarly, you can't pass a three element array to a method that expects three parameters (excepting params, of course).

1 Comment

I was actually hoping the multidimensional array indexer was implemented as params :) Oh well.
1

No, c# arrays are only indexed by integer values. You will have to manually traverse your array with integers.

If you need to index by another type, consider using Dictionary<TKey, TValue>

1 Comment

Yeah I had considered using my Point class (having an x and y property) as the key in a Dictionary but then you end up with a "sparse" collection as there is no guarantee every element is accounted for as you get with a multidimensional array. This is a good alternative though.
1

You can not do that directly, instead you can write a generic method which would use GetValue Like:

class MyGenericClass<T>
{
    public static T GetValue(T[,] array, params int[] indices) 
    {
        return (T)array.GetValue(indices);
    }
}

and later you can do:

int val = MyGenericClass<int>.GetValue(nums, new[] { 0, 2 });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.