tags:

views:

112

answers:

3

I have many math types like Point3, and I am running into the dilemma of implementing operators, instance and static methods for arithmetic.

So say the type is Point3. Where a, b, c is a Point3, I sure wanna be able to say:

c = a + b;

But should I also implement:

c = Point3.Add (a, b);

And this:

c = a.Add (b);

To me #3 is useless and less readable than #1. And #2 seems like pointless unless you have an interface for Add, Subtract, Multiply, Divide, etc.

What do you recommend? Is there any problem or drawback with just having the operators (+, -, *, /)? Would this impede the generics arithmetic (I know it doesn't support it directly, but maybe having static methods would be useful in a workaround)?

Would a guidelines for this matter whether it's a class or a struct?

EDIT: Also for #3, I forgot to mention that this is for an immutable type, so returns a new Point3, instead of changing a.

+3  A: 

In general, I think Microsoft seems to have kind of done A+B in most of their classes similar to this.

For samples, see the entire System.Windows.Media.Media3D namespace, as well as the XNA math classes. Both have point/vector/quaternion/matrices/etc, and use Class.Operator(a,b), and occasionally do c = a + b;

Personally, I would do the first where it makes sense and is clear, and always do the second option. I usually implement the first using the second option (the operator is implemented using the static method).

Reed Copsey
Thanks Reed. Yeah I also took a look at xna and they have both static add method and operator overload. I did the same but, why shouldn't you only implement the operator? Also when you said you would always use the second option, what do you mean? You wouldn't always use a+b?
Joan Venge
For things like point it seems rather trivial, but what about a something like User, where you may overload the + operator to yield children (not that this is a good practice.)List<User> children = new User("Mary") + new User("John");it may not be clear exactly what the plus operator is doing here, so having a method GetChildren(User a, User b) will make more senes to some of your API users.List<User> children = User.GetChildren(new User("Mary"), new User("John"));
Matthew Vines
@Joan: I always implement the static method. I think this is expected, since it's potentially more explicit in certain cases. I do like operators when they make sense, though, such as adding a point + vector, or 2 vectors. But, take that case - point+vector makes sense, vector+vector makes sense, but point+point does not - and static methods make things very clear and easy to find in intellisense.
Reed Copsey
@Matthew: In the case of something like User, I would always use methods. I only overload operators when it makes sense to do so, but in terms of simplicity, but also meaning. I'd provide point+vector, as I mentioned above, but would never even consider any operator overloading on a User class. (Frankly, if the static method's name is not the same as the operator name, I think its inappropriate. IE: If you overload +, there should always be a .Add(a,b) IMO)
Reed Copsey
+2  A: 

Use operator overloads to meet your needs. To honor .NET languages that do not support overloaded operators, include static methods that wrap the operators (or the other way around). The third option is only viable if you are using reference types and want to avoid instantiating new ones.

Cecil Has a Name
+1  A: 

Languages, such as VB.NET, don't have operator overloading like C# does so they need static methods like your Point3.Add(a, b) to provide addition and other arithmetic operations. If you want your type to be CLR-compliant, you have to support these other languages by providing these method implementations.

Although VB.NET (and other language) programmers could use the op_Addition call created when the + overload is compiled, it is nicer to access an Add method. This MSDN section describes the alternative method names for each operator.

The third option you describe is not required for CLS-compliance.

Jeff Yates
Thanks. Would CLS-compliance throw a warning if I don't have those static methods? I believe it doesn't. But I can see it being part of the compliance.
Joan Venge
That's a good question. I don't know if the compiler would spot your CLSCompliantAttribute value or not, and what it would do. FxCop or Team System Code Analysis would no doubt pick this up though.
Jeff Yates
How do they pick it up? I guess they look for the suggested Add, Subtract method names, right?
Joan Venge
To my knowledge Visual Basic.NET 8 (and above) supports operator overloading, even defining new ones.
Cecil Has a Name
@Cecil: I believe that yes, since VB 2005, operator overloading is supported - but prior to that, it is not.
Jeff Yates