15

Possible Duplicate:
Arithmetic operator overloading for a generic class in C#

Here is the code for generic class i have created to add the complex number to overload operator.

public class Complex<T>
{
    public T _a, _b;
    public Complex(T i, T j)
    {
        _a = i;
        _b = j;
    }
    public static Complex<T> operator +(Complex<T> i, Complex<T> j)
    {
        return new Complex<T>(i._a + j._a, i._b + j._b);
    }
}

while working with this i have got an error of,

Error: Operator '+' cannot be applied to operands of type 'T' and 'T'

can any one suggest me the way i can use operator overloading with generics?

Community
  • 1
  • 1
Sujit
  • 3,677
  • 9
  • 41
  • 50
  • 1
    http://stackoverflow.com/questions/756954/arithmetic-operator-overloading-for-a-generic-class-in-c-sharp – Habib Dec 24 '12 at 11:10
  • and also: http://stackoverflow.com/questions/147646/solution-for-overloaded-operator-constraint-in-net-generics Not being able to define value types with operator overloading is a serious limitation of C#. There simply is no satisfying work around available. – citykid Dec 24 '12 at 11:33
  • This should not be generic in the first place. Only make a generic when it makes sense to have **any** type in there; that's why they're called *generics*. – Eric Lippert Dec 24 '12 at 14:46

4 Answers4

28

The problem is the compiler cannot know if + operator can be applied to T. Unfortunately, there is no way to constraint T to be a numeric type in C#.

However, you might be able to workaround this using the dynamic runtime:

public class Complex<T> where T : struct
{
    public T _a, _b;
    public Complex(T i, T j)
    {
        _a = i;
        _b = j;
    }
    public static Complex<T> operator +(Complex<T> i, Complex<T> j)
    {
        return new Complex<T>(Sum(i._a, j._a), Sum(i._b, j._b));
    }

    private static T Sum(T a, T b)
    {
        return (dynamic)a + (dynamic)b;
    }
}
Eren Ersönmez
  • 38,383
  • 7
  • 71
  • 92
  • Wow. I have seen this question many times, but I have never seen this answer. I reverted to emitting op codes in the past to do what the `(dynamic)` cast appears to do. Interesting. – John Alexiou Dec 25 '12 at 04:59
2

If you want to cheat, you can temporarily mark them as dynamic type and allow the runtime to determine how to do it. As long as the type T that you use defines the + operator, it will work. That means it will work for both numbers and strings, or whatever type (custom or otherwise); not sure if that's your intent for Complex or not. Additionally, if there is no + operator to leverage, an exception will throw at runtime; there is no way (that I know of) to do compile time checking for this.

public class Complex<T>
{
    public T _a, _b;
    public Complex(T i, T j)
    {
        _a = i;
        _b = j;
    }
    public static Complex<T> operator +(Complex<T> i, Complex<T> j)
    {
        dynamic d_i = i;
        dynamic d_j = j;
        return new Complex<T>(d_i._a + d_j._a, d_i._b + d_j._b);
    }
}

Sample usage with strings:

Complex<string> i = new Complex<string>("Hel", "Wor");
Complex<string> j = new Complex<string>("lo ", "ld!");

Complex<string> ij = i + j;

Console.WriteLine(ij._a + ij._b); //Hello World!
Chris Sinclair
  • 22,858
  • 3
  • 52
  • 93
1

As mentioned above, you could constrain T to be IConvertible and then use the decimal type to perform the desired mathematical function as follows:

public class Complex<T> where T : struct, IConvertible
{
    public T _a, _b;

    public Complex(T i, T j)
    {
        _a = i;
        _b = j;
    }

    public static Complex<T> operator +(Complex<T> i, Complex<T> j)
    {
        return new Complex<T>(Sum(i._a, j._a), Sum(i._b, j._b));
    }

    private static T Sum(T a, T b)
    {
        return (T)Convert.ChangeType(a.ToDecimal(CultureInfo.CurrentCulture) + b.ToDecimal(CultureInfo.CurrentCulture), typeof(T));
    }
}
jam40jeff
  • 2,576
  • 16
  • 14
0

You cannot sum two generic object type; in the static function you trying to add two elements of type T i._a and j._a., but T can be of any type

what you try to do ?

Max
  • 6,821
  • 3
  • 43
  • 59