如何编写可能返回两种不同类型的方法?

时间:2014-05-05 18:24:35

标签: c# .net methods return boxing

我有一个名为Vector的类,我实现了乘法运算符,这是我的实现:

public static Object operator *(Vector x, Vector y)
{

    //Possible return objects
    Matrix multiplicationResultMatrix;
    float multiplicationResultScalar = 0f;


    if (x.VectorType != y.VectorType)
    {
        if (x.Length == y.Length)
        {
            if ((x.VectorType == VectorType.Row) && (y.VectorType == VectorType.Column))
            {
                for (ulong i = 0; i < x.Length; i++)
                {
                    multiplicationResultScalar += x[i] * y[i];
                }
            }
            else
            {
                if ((x.VectorType == VectorType.Column) && (y.VectorType == VectorType.Row))
                {
                    multiplicationResultMatrix = new Matrix(x.Length);
                    for (ulong j = 0; j < x.Length; j++)
                    {
                        for (ulong i = 0; i < x.Length; i++)
                        {
                            multiplicationResultMatrix[i, j] += x[i] * y[j];
                        }
                    }
                }
            }
        }
        else
        {
            throw new ArithmeticException("Unhandled Arithmetic Exception, Multiplication of two vectors of different length is not allowed");
        }
    }
    else
    {
        throw new ArithmeticException("Unhandled Arithmetic Exception, Multiplicating vectors of the same type is not allowed");
    }

    //What should I return
    return ?
}

我应该如何定义返回类型?我考虑过装箱,并在消费时取消装箱,但我认为这不是一个安全的解决方案。

更新:

我还想过只返回一个矩阵对象,因为标量是1x1矩阵,问题是矩阵类得到了一些复杂的方法和特性,在1x1的情况下不能正常工作(这将迫使我添加一些代码),加上我想最小化和优化计算,我处理数百万的矩阵乘法。

3 个答案:

答案 0 :(得分:5)

您应该避免根据输入参数的值更改返回类型(与编译时已知的静态类型相反)。这使得来电者可以完成您方法工作的一部分,即找出返回的内容。

有两种解决方案:

  • 始终返回相同类型的对象 - 您的方法将返回NxN矩阵或1x1矩阵,具体取决于列或行是先到还是
  • 使用不同类型定义单独的方法 - 不使用运算符,而是使用MultiplyRowColMultiplyColRow方法,返回不同类型的对象。

从技术上讲,第一种解决方案更好,因为逐行乘法会产生一个带有单个元素的矩阵,而不是标量。

答案 1 :(得分:3)

C#对和类型的支持非常有限,但它是可能的。有一个nice implementation of a Discriminated Union here on StackOverFlow。使用此方法,您的方法可能如下所示:

public static Union2<Matrix, float> operator *(Vector x, Vector y)
{
    (...)
    return multiplicationResultMatrix != null 
        ? new Union2<Matrix, float>.Case1(multiplicationResultMatrix)
        : new Union2<Matrix, float>.Case2(multiplicationResultFloat);
}

请注意,我实际上并不建议在这种情况下执行此操作,因为我同意其他海报,总是返回矩阵会更好的设计。但你知道,这是可行的。

答案 2 :(得分:0)

如果他们没有共同的基类或接口,那么Object是您唯一的选择。