2

I am newbie in C#. I need to create a generic class. There should be one constraint also : "client can implement by Int or Float class". Contains a 'totalNums' method which will return total.

Generic Class

public class clsPrint<T>
{      

    public T totalNums(T num1, T num2)
    {
        T Total = num1 + num2;
        return Total;
    }        

}

Compile time error on "Num1 + Num2" : Operator '+' cannot be applied to operands of type 'T' and 'T'.

Why I am getting this error and what will be the solution?

GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
KiddoDeveloper
  • 568
  • 2
  • 11
  • 34
  • When writing generics, `T` is basically treated as `object` when you are writing the code. Therefore, `object + object` doesn't make any syntactic sense. – Abion47 Dec 30 '16 at 05:27
  • So, is there any other way to achieve it? @Abion47 – KiddoDeveloper Dec 30 '16 at 05:29
  • Strictly speaking, there's a way using reflection and abstraction (see my duplicate comment), but it's pretty ugly. In general, I'd suggest not using generics at all for this, but rather use two different method overloads: one that takes `int` parameters, and one that takes `float` parameters. – Abion47 Dec 30 '16 at 05:34
  • Thank you. Actually, I wanted to practice Generic class. So this idea came in mind. – KiddoDeveloper Dec 30 '16 at 05:35
  • Don't do that in the first place. If it can only be instantiated with int and float then it is not *generic*. Simply make two classes, one for int operations and one for float operations. – Eric Lippert Dec 30 '16 at 05:37

1 Answers1

1

Because the type of T is not known until instantiation, there is no guarantee that the type T will support the + operator.

There's a workaround using dynamic operator: (note: if you don't pass + supported operands then it WILL throw a runtime error.)

public T totalNums(T num1, T num1)
        {
            dynamic dx = num1, dy = num1;
            return dx + dy;
        }
canon
  • 40,609
  • 10
  • 73
  • 97
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
  • So, is there any other way to achieve it? – KiddoDeveloper Dec 30 '16 at 05:29
  • Fine. Can I add Int, Float or string class as a constraint class? Example : public class clsPrint where T : String – KiddoDeveloper Dec 30 '16 at 05:34
  • 1
    @Mohit `int`, `float`, and `string` are sealed classes. You cannot use sealed classes as generic constraints. – Abion47 Dec 30 '16 at 05:35
  • Thank you @Abion47. – KiddoDeveloper Dec 30 '16 at 05:37
  • 1
    @Abion47: `int`, `float` and `string` are keywords. `int` denotes `System.Int32` and `float` denotes `System.Single` both of which are `structs`. Structs are `value types` and `value types` are sealed. Also `string` denotes the sealed class `System.String`. – Sani Huttunen Dec 30 '16 at 05:53
  • You can also use your original code and attempt to cast the objects to a specific type (i.e. int.parse(t.ToString()) or Convert.ToDouble(t)) but you'll still get errors if they don't cast properly. – CDove Dec 30 '16 at 15:55
  • @user1895086 That approach completely defeats the purpose of using generics. – Abion47 Dec 30 '16 at 22:19