Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can one specity "convertability from int" as a type constraint in C#?

I have some code that looks like this:

class A<T>
      where T : // what should I say here to make this work?
{
   void foo()
   {
      int x = 0;
      T y = (T)x; // this is a compile error without proper type restrictions
   }
}

The intent is to use A with types like double, float, int.

like image 646
user1124310 Avatar asked Mar 07 '15 23:03

user1124310


3 Answers

You can't have a type constraint for this, unfortunately. However, you can use the Convert.ChangeType method.

class A<T>
{
   void foo()
   {
      int x = 0;
      T y = (T)Convert.ChangeType(x, typeof(T));
   }
}

This won't stop you from instantiating the class with a type that can't be converted from an int, though.

like image 198
Random832 Avatar answered Oct 05 '22 19:10

Random832


int, float, double keywords are just syntactic sugar. The compiler maps them to value types like Int32, Float, Double etc (which are structs). Generally you can't force a type T to be a only a primitive type but you can impose T to be a value type by doing:

class A<T>
  where T : struct
{
   void foo()
   {
      int x = 0;
      T y = (T)Convert.ChangeType(x, typeof(T));  
   }
}

Please note that you still need to use Convert.ChangeType as pointed out by Random832. Imposing the type T to be a struct is only to exclude classes (which are not value types). It's not a great advantage but I think it's cleaner.

There is a similar question here anyway.

hope it helps.

like image 40
codingadventures Avatar answered Oct 05 '22 20:10

codingadventures


I can suggest one way to do it(but it's far from being elegant, to be honest):

interface IConvertsFromNumeric<T>
{
    T FromLong(long x);
    T FromDouble(double x);
    T FromDecimal(decimal x);
}

class A<T>
  where T : IConvertsFromNumeric<T>, new()
{
   void foo()
   {
      int x = 0;
      T y = new T().FromLong(x);
   }
}
like image 43
alex.b Avatar answered Oct 05 '22 19:10

alex.b