Extend an existing struct in C# to add operators
There is no way to do it with the built in operators.
You could write an extension method to kind of fake it though:
public static class Extensions
{
public static Color Substract(this Color color, Color theOtherColor)
{
//perform magic here!
//be sure to return something or this won't compile
}
}
Color c1 = Color.FromName("Red");
Color c2 = Color.FromName("Blue");
Color result = c2.Subtract(c1);
As others suggested, you can go either the extension methods way or the Decorator pattern way.
However, consider that Color has a fair number of properties and methods, so redirecting them all from the decorator class to your wrapped Color struct will mean writing a lot of boilerplate. If you go that route, however, you can indeed define operators and even implicit conversions from your class to Color and the other way around (so that you can use them more interchangeably), like this:
public class MyColor {
public System.Drawing.Color val;
public MyColor(System.Drawing.Color color)
{
this.val = color;
}
public static MyColor AliceBlue
{
get {
return new MyColor(System.Drawing.Color.AliceBlue);
}
}
public override string ToString()
{
return val.ToString();
}
// .... and so on....
// User-defined conversion from MyColor to Color
public static implicit operator System.Drawing.Color(MyColor c)
{
return c.val;
}
// User-defined conversion from Color to MyColor
public static implicit operator MyColor(System.Drawing.Color c)
{
return new MyColor(c);
}
}
to test:
MyColor c = System.Drawing.Color.AliceBlue; // assigning a Color to a MyColor
// thanks to the implicit conversion
Console.WriteLine(c.ToString()); // writes "Color [AliceBlue]"
Structs and Classes in C# share a lot of similarities, however one of several difference is that you cannot subclass a struct. You could use an extension method to implement an Add() or Subtract() method, but you cannot write an operator overload in an extension method.
If I were you and I really wanted to extend the functionality of an existing struct like this, I would wrap the struct in my own class.