bto.rdz bto.rdz - 1 year ago 80
C# Question

Generic decimal can't cast from double

I don't see why this is not working, I can do a direct cast from

with no problem, but unexpectedly I can't do this cast if it is inside a generic class, this snippet explains it better:

public class TestCollection<T>
public void Add(object value)
//When T is decimal, then I get
// System.InvalidCastException
var t = (T) value;

public void Main ()
var t = new TestCollection<decimal> ();
double doub = 10;

var decim = (decimal) doub; //Works!
t.Add(doub); //throws!

System.InvalidCastException was unhandled by user code
Message=Specified cast is not valid.
at Wpf.TestCollection`1.Add(Object value) in C:\Users\btord\Source\Repos\Live-Charts\Examples\Wpf\JimmyTheTestsGuy.xaml.cs:line 15
at Wpf.JimmyTheTestsGuy..ctor() in C:\Users\btord\Source\Repos\Live-Charts\Examples\Wpf\JimmyTheTestsGuy.xaml.cs:line 35
at Wpf.MainWindow..ctor() in C:\Users\btord\Source\Repos\Live-Charts\Examples\Wpf\MainWindow.xaml.cs:line 56

Answer Source

It fails due to the exact same reason why the following fails:

short i = 1;
object o = i;
var d = (int)o; //Runtime error

The reason being that a boxed value can only be unboxed to its real type. In your case your are boxing a double and trying to unbox it to a decimal. That is not allowed.

I'd push back on the whole design. You have a generic collection of Ts. Your Add method should simply accept Ts and let the caller carry the burden of converting to the right type. If that's not a valid solution then get rid of generics all together and simply implement a collection of objects.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download