views:

107

answers:

4

I need to define an Interface which has to enforce certain operator overloading to the types which implements it. There doesn't seem an obvious way to do it since operator overloading has to be done using static methods in class. Is there any way to achieve the same effect (using abstract classes or anything else)?

+2  A: 

No. The only sensible way to do this would be to have a unit test check use reflection to find all concrete implementations, and then verify this condition. You could also perhaps do something at runtime re the same via a static constructor, but then the question is which static constructor?

Another approach is to drop the operators and use an interface-based approach; for example , if you need T to have +(T,T) then instead of operators have an interface with an Add(T) method. Another advantage here is that interfaces are usable from generics (typically via constraints), where-as using operators from generic code takes some effort.

Marc Gravell
Using methods like Add, Subtract is next obvious choice but since my code will have lots of calculations like `s = s1 * 2 + s2 * s3 - s4 * (s5 - s6);`. Using methods will make it `s = s1.Multiply(2).Add(s2.Multiply(s3)).Subtract(s4.Multiply(s5.Subtract(s6)));` Certainly not very readable!
Hemant
@Hemant: You can use apostrophe ` to highlight code into comments too
abatishchev
@abatishchev fixed that ;p
Marc Gravell
@Marc: Great! Thanks :)
abatishchev
+3  A: 

You could implement the overloading in an abstract base class, but delegate the actually operation specifics to an abstract method. Then this will have to be implemented and the overloading will be don with their implementation.

public abstract class OverLoadingBase
{
    public abstract OverLoadingBase DoAdd(OverLoadingBase y);

    public static OverLoadingBase operator +(OverLoadingBase x, OverLoadingBase y)
    {
        return x.DoAdd(y);
    }    
}

Though I'm not sure if this is complete.

Preet Sangha
@abatishchev - I'm curious - why the brace format change?
Preet Sangha
+8  A: 

Bit of a hack, but...

You could provide operator overloads in your base class that then call some published abstract methods in one of the classes to do the job there.

public abstract class MyClass
{
    public static MyClass operator +(MyClass c1, MyClass c2) 
    {
        return c1.__DoAddition(c2);
    }

    protected abstract MyClass __DoAddition(MyClass c2);
}
Codesleuth
`protected abstract` instead of `private abstract`, I guess..
abatishchev
Not nice, but effective. I'm also doing it this way.
elsni
@abatishchev: whoops, thank you :)
Codesleuth
The problem with this is that the return type is `MyClass`, not the overriding class. This makes chaining rather risky, and chaining is the intent here.
Marc Gravell
@Marc, @Code: Probably it's better to return an interface? e.g. IMyClass forcing implement DoAddition(), therefore make it public
abatishchev
@abatishchev: But returning an interface will again prevent chaining which as Marc mentioned, is essential!
Hemant
+1  A: 

Since its operator can only be overloaded and not overridden its quite difficult. The best solution I can think of is use an abstract class and overloading like this.

public abstract class MyBase
{
    public abstract MyBase Add(MyBase right);
    public abstract MyBase Subtract(MyBase right);

    public static MyBase operator +(MyBase x, MyBase y)
    {
        //validation here
        return x.Add(y);
    }

    public static MyBase operator -(MyBase x, MyBase y)
    {
        //validation here
        return x.Subtract(y);
    }
}
Bear Monkey