二元运算符的其中一个参数必须是包含类型c#

Sil*_*tya 6 .net c# visual-studio-2010 visual-c#-express-2010

public static int[,] operator *(int[,] arr1, int[,] arr2)
    {
        int sum;
        int[,] res = new int[arr1.GetLength(0), arr2.GetLength(1)];
        for (int i = 0; i < arr1.GetLength(0); i++)
        {
            for (int j = 0; j < arr2.GetLength(1); j++)
            {
                sum = 0;
                for (int k = 0; k < arr1.GetLength(1); k++)
                {
                    sum = sum + (arr1[i, k] * arr2[k, j]);
                }
                res[i, j] = sum;
                //Console.Write("{0} ", res[i, j]);
            }
            //Console.WriteLine();
        }

        return res;
    }
Run Code Online (Sandbox Code Playgroud)

这里我试图重载*运算符乘以两个矩阵..但编译器继续向我显示错误..

"二元运算符的一个参数必须是包含类型c#"

请告诉我我的代码中有什么问题以及如何解决它.

Jon*_*eet 8

编译器已经告诉你出了什么问题 - 但引用C#5规范的第7.3.2节:

用户定义的运算符声明始终要求至少有一个参数属于包含运算符声明的类或结构类型.因此,用户定义的运算符不可能具有与预定义运算符相同的签名.

换句话说,拥有:

class Foo
{
    public static int[,] operator *(int[,] arr1, Foo arr2)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

...因为那时第二个操作数是声明类型.但在你的情况下,两个操作数都是int[,].

可以做的是添加扩展方法:

public static class ArrayExtensions
{
    public static int[,] Times(this int[,] arr1, int[,] arr2)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以:

int[,] x = ...;
int[,] y = ...;
int[,] z = x.Times(y);
Run Code Online (Sandbox Code Playgroud)

另一个解决方案 - 更好的一个,IMO,将声明自己的Matrix类来封装矩阵操作.然后,您可以定义自己的乘法运算符:

public static Matrix operator *(Matrix left, Matrix right)
Run Code Online (Sandbox Code Playgroud)

...而且你不会干扰int[,]那些不打算被视为矩阵的数组.