locked
Operators in generic interface

    Question

  • I want to define an interface that override operators (like '+', '*' etc.), but the compiler doesn't let me to it. From what I sow in the web there is an option to override operators only in classes but I couldn't find example how to it with interface.

    The interface should be something like:

    public interface BaseMathOperators<T>

    {

        T operator +(T left, T right);

        T operator -(T left, T right);

        T operator *(T left, T right);

    }

     

     

    public class MathSet<T> : List<T>  where T : BaseMathOperators<T> ,new()

    {

        public T getSetSum()

        {           

            T sum = new T();           

            foreach (T item in this)

            {

                sum = sum + item;

            }

            return sum;

        }   

        all the others methods...

    }

    I will appreciate any help with this problem…

    Friday, March 30, 2012 11:47 AM

Answers

  • What servy42 says is true. Operators can not be defined in an interface, because they are static and interfaces can not have static members.

    Besides that it is not possible to define a generic overloaded operator such as this:

    class MyMath<T>
    {
    	public T Add(T a, T b) { return a + b; }
    }

    Even if you define a value-type-constraint for the generic parameter compiler still generates error.

    class MyMath<T> where T: struct
    { ... }

    The reason is that the type specified for the generic parameter when instantiating the class MUST have those operators and there's no constraint in .NET (at least so far) which can impose that.

    You can use delegates instead.

    class MyMath<T>
    {
    	public delegate T TAddMethod(T a, T b);
    	public TAddMethod AddMethod;
    	public T Add(T a, T b) { return AddMethod(a, b); }
    }
    ...
    var m = new MyMath<int>();
    m.AddMethod = (a, b) => { return a + b; };
    Console.WriteLine(m.Add(3, 4));  // output: 7


    Tuesday, April 03, 2012 4:54 AM
  • Operator overload aren't instance members of a class.  They are static methods.  Instances can't define static methods, so you won't be able to define an interface that indicates that a particular class has a particular operator overload defined.

    About the best that you could get for your mathset would be to take several Func<T, T, T> parameters in the constructor to which you could pass your arithmetic operations for use later on.  Those functions could be passed in, from the point of view of the caller, using the operators. 

    Friday, March 30, 2012 2:15 PM

All replies

  • Operator overloading only works with the type that the operator is in. So your + operator would have to be

    public static BaseMathOperators<T> operator + (BaseMathOperators<T> c1,BaseMathOperators<T> c2);

    Trying to define the operator with T would be like trying to override the + operator for integers...

    Friday, March 30, 2012 12:29 PM
  • Operator overload aren't instance members of a class.  They are static methods.  Instances can't define static methods, so you won't be able to define an interface that indicates that a particular class has a particular operator overload defined.

    About the best that you could get for your mathset would be to take several Func<T, T, T> parameters in the constructor to which you could pass your arithmetic operations for use later on.  Those functions could be passed in, from the point of view of the caller, using the operators. 

    Friday, March 30, 2012 2:15 PM
  • What servy42 says is true. Operators can not be defined in an interface, because they are static and interfaces can not have static members.

    Besides that it is not possible to define a generic overloaded operator such as this:

    class MyMath<T>
    {
    	public T Add(T a, T b) { return a + b; }
    }

    Even if you define a value-type-constraint for the generic parameter compiler still generates error.

    class MyMath<T> where T: struct
    { ... }

    The reason is that the type specified for the generic parameter when instantiating the class MUST have those operators and there's no constraint in .NET (at least so far) which can impose that.

    You can use delegates instead.

    class MyMath<T>
    {
    	public delegate T TAddMethod(T a, T b);
    	public TAddMethod AddMethod;
    	public T Add(T a, T b) { return AddMethod(a, b); }
    }
    ...
    var m = new MyMath<int>();
    m.AddMethod = (a, b) => { return a + b; };
    Console.WriteLine(m.Add(3, 4));  // output: 7


    Tuesday, April 03, 2012 4:54 AM