Question

I have a class named Vector, to which I'm implementing the multiplication operator, here's my implementation :

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

How should I define the return type ? I thought about boxing them, and unboxing when consuming them, but I don't think it's a good safe solution.

Update :

I have thought also about just returning a matrix object, since the scalar is a 1x1 matrix, the problem is that the matrix class got some complexe methods and properies that wouldn't just work fine in the case of 1x1 (that would force me to add some code), plus I want to minimize and optimize calculations, I'm handling matrices multiplications of the range of millions.

Was it helpful?

Solution

You should refrain from changing the return type based on the values of the input parameters (as opposed to, say, a static type known at compile time). This makes the caller do part of your method's job, i.e figuring out what has been returned.

There are two solutions to this:

  • Always return an object of the same type - Your method would return either an NxN matrix, or a 1x1 matrix, depending on whether the column or the row comes first, or
  • Define separate methods with different types - Instead of using the operator, make MultiplyRowCol and MultiplyColRow methods, returning objects of different kinds.

Technically speaking, the first solution is better, because a multiplication of a row by column produces a matrix with a single element, not a scalar.

OTHER TIPS

C# has very limited support for sum types, but it is possible. There's a nice implementation of a Discriminated Union here on StackOverFlow. Using this, your method could look like:

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

Note that I don't actually recommend doing this in this case, as I agree with other posters that it would be better design to always return a Matrix. But just so you know, it is feasible.

If they don't have a common base class or interface then Object is your only choice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top