重载运算符[]用于单维数组

时间:2014-04-29 17:03:31

标签: c# arrays performance operator-overloading

要解决我已在此处Best/Fastest Way To Change/Access Elements of a Matrix

提出的问题

我使用单维数组来存储矩阵。但访问矩阵的元素变得很麻烦。

我目前正在将矩阵存储在像这样的数组

type[numberOfRows * numberOfColumns] myArray;

要访问[n][m]元素,我必须输入此

blargh = myArray[(n*numberOfRows)+m];

...我想知道是否有可能超载/创建新的操作符[][],这些操作符会翻译成“#{1}}。 myArray[n][m]myArray[(n*numberOfRows)+m]。如果这是可能的话,那会对性能造成太大影响。

编辑:结果显示强制内联'方法产生性能增益。

    [MethodImpl(MethodImplOptions.AggressiveInlining)]public void set(int x, int y, T value)
    {
        array[(x * wid) + y] = value;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]public T get(int x, int y)
    {
        return array[(x*wid) + y];
    }

2 个答案:

答案 0 :(得分:2)

不可能为数组类型重载运算符,或更改其定义;这只能通过你无法控制的那种类型的定义来完成。

可以做的是创建自己的包装数组的类型,并重载你想要的运算符:

public class Matrix<T>
{
    private T[] array;

    public T this[int row, int column]
    {
        get { return array[row + column]; }
    }
}

您的程序是否存在性能差异(应该很小,但不是没有)是您需要进行分析和衡量的问题。

答案 1 :(得分:1)

实现双索引(即matrix[r][c]语法)的一种方法是使用Proxy Pattern(也称为代理模式)。

我们的想法是重写顶级operator[]以返回一个特殊的对象,该对象会记住&#34;第一个索引和数组,并提供自己的operator[]重载,它结合了#34;记住&#34;第一级索引与提供的第二级索引产生实际的&#34;平坦&#34;索引到数据数组。

就程序逻辑而言,代理对象代表矩阵的列。以下是如何实现这一点:

public class Matrix<T> {
    private readonly T[] data;
    private readonly int rowCount;
    public class Column {
        private readonly Matrix<T> m;
        private readonly int r;
        internal Column(Matrix<T> m, int r) {
            this.m = m;
            this.r = r;
        }
        public T this[int c] {
            get {
                return m.data[m.rowCount*r + c];
            }
        }
    }
    public Column this[int r] {
        get {
            return new Column(this, r);
        }
    }
}

这种方法的性能影响是每次访问顶级矩阵时都会创建一个对象。