non-overridable operators...

O

Oscar Papel

Hello,

I have a c# class that holds a large matrix of data.
I overrode the standard +, - operators but I also need to override the +=
and -= operators in order to avoid making a copy of the entire matrix.
The code below should explain...

From what I can tell, the ECMA spec does not allow for overriding of A+=B
and expands it to A=A+B
This is a huge waste of memory for my app.
Instead, I have to force the user of the class to use A.Add(B) .

Is there anything I can do or am I stuck?

How do I go about requesting this ability for the next version of the
language?

Also, Is there a way of adding custom operators to the language or is the
list of operators set in stone?

I would also love to see an overrideable Min/Max operator.
Sometimes, Math.Min doesn't cut it.

<code>
public class Matrix {

// this is what I'd like to do...
public static void operator += (Matrix A,Matrix B) { A.Add(B); }

// but this is what I have to do
public static Matrix operator + (Matrix A, Matrix B) { return
Matrix.Add(A,B); }

public static Matrix Add (Matrix A, Matrix B) {
Matrix retval=new Matrix(A) // <--- I want to avoid having to
reallocate a new matrix
retval.Add(B);
return retval;
}

public void Add(Matrix B) { ... add code here }
}
</code>

I could change the code above to always use the A matrix but then expresions
like C=A+B would be misleading since A would also change.

Thanks in advance,

Oscar
 
J

Jon Skeet

I could change the code above to always use the A matrix but then expresions
like C=A+B would be misleading since A would also change.

But that would also be the case if you had += doing what you want. Take
this example:

Matrix original = ...;

Matrix a = original;
Matrix b = original;

a+=b; // a should now just be twice b, right?

Nope - now a, b and original have *all* changed.

I would be very, very wary of *any* class where a+=b wasn't
semantically equivalent to a=a+b, if it were possible in C#.
 
O

Oscar Papel

Jon Skeet said:
But that would also be the case if you had += doing what you want. Take
this example:

Matrix original = ...;

Matrix a = original;
Matrix b = original;

a+=b; // a should now just be twice b, right?

Nope - now a, b and original have *all* changed.

This would be true if Matrix was a class but not if it was a struct.
Then, A=original and B=original would do a Copy() instead of a reference
copy and then A+=B would be semantically equivalent to A=A+B but there would
be no need to allocate a temporary matrix in order to do the operation.
Your example is a classic example of why "value" types are needed in C#
I never said that I wanted the semantic meaning to change, I merely said I
wanted to perform the operation more efficiently.

Also, A+=ScalarValue shouldn't need to allocate a new copy of A but it does.

C#'s GC only adds to the problem.

Oscar.
 
J

Jon Skeet

This would be true if Matrix was a class but not if it was a struct.
Then, A=original and B=original would do a Copy() instead of a reference
copy and then A+=B would be semantically equivalent to A=A+B but there would
be no need to allocate a temporary matrix in order to do the operation.

Yes, that's true.
Your example is a classic example of why "value" types are needed in C#
I never said that I wanted the semantic meaning to change, I merely said I
wanted to perform the operation more efficiently.

Except that your example was a class, so the semantics *would* have
changed...
Also, A+=ScalarValue shouldn't need to allocate a new copy of A but it does.

Only in the same way - you could make Add(Matrix, int) change the
passed in matrix, it just wouldn't be a terribly nice thing to do.
C#'s GC only adds to the problem.

GC is a CLR concept, not particularly a C# one. However, I don't see
how it has much to do with this problem at all.

Overall I'd stick with using method names - it's likely to be clearer
to maintain, IMO.
 
S

Simon Trew

does.

Only in the same way - you could make Add(Matrix, int) change the
passed in matrix, it just wouldn't be a terribly nice thing to do.

Well surely you can't object to

struct /* or class */ Matrix
{
...
public void Add(float f); // Adds f to "this"
}
Overall I'd stick with using method names - it's likely to be clearer
to maintain, IMO.

I agree-- especially as some languages don't allow operator overloading
anyway so you are recommended to publish methods that accomplish the same
purpose.

Incidentally a Matrix class is a good candidate for having generics where
the parameters are not types. For example in C++:

template<int rows, int columns> class Matrix
{
...
};

produces a unique type for each matrix of differet
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top