【问题标题】:Can you access a C# multidimensional array indexer using an array?您可以使用数组访问 C# 多维数组索引器吗?
【发布时间】:2014-01-23 20:37:12
【问题描述】:

我试图弄清楚是否可以将对象作为多维数组的索引值传递。

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

那么有谁知道我应该将什么类型传递给多维数组索引器以满足编译器的要求?

【问题讨论】:

    标签: c# multidimensional-array indexing


    【解决方案1】:

    简短的回答是不,你不能在本地做到这一点。

    略长一点的答案是肯定的,您可以使用扩展方法来实现这样的行为。您可以添加一个适用于所有数组的扩展方法,如下所示:

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

    你可以使用:

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

    输出:

    Old Value = 99
    New Value = 100
    

    在大多数情况下,有一个面向对象的答案来解释您为什么需要此功能,并且可以创建适当的自定义类来促进这一点。例如,我可能有一个棋盘,我用辅助方法创建了几个类:

    class GameBoard
    {
      public GamePiece GetPieceAtLocation(Point location) { ... }
    }
    

    【讨论】:

    • 正如您所指出的,确实有一个很好的 OO 解决方案。我将按照您的建议将索引器添加到我的自定义类中,并让它接受我的 Point 类作为索引。
    【解决方案2】:

    不,你不能这样做。数组索引器是语法上的,它们不是“虚拟”数组。这意味着它需要一系列用逗号分隔的表达式,而不是可能表示数组的表达式。

    同样,您不能将三元素数组传递给需要三个参数的方法(当然,params 除外)。

    【讨论】:

    • 我实际上希望多维数组索引器被实现为参数 :) 哦,好吧。
    【解决方案3】:

    不,c# 数组仅由整数值索引。您将不得不手动遍历您的整数数组。

    如果您需要按其他类型进行索引,请考虑使用Dictionary&lt;TKey, TValue&gt;

    【讨论】:

    • 是的,我曾考虑使用我的 Point 类(具有 x 和 y 属性)作为 Dictionary 中的键,但最终会得到一个“稀疏”集合,因为不能保证每个元素都被计算在内因为你得到一个多维数组。不过,这是一个不错的选择。
    【解决方案4】:

    您不能直接这样做,而是可以编写一个通用方法来使用GetValue Like:

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

    以后你可以这样做:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2016-07-16
      相关资源
      最近更新 更多