bto.rdz bto.rdz - 2 months ago 8
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

double
to
decimal
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
HResult=-2147467262
Message=Specified cast is not valid.
Source=Wpf
StackTrace:
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
InnerException:

Answer

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.

Comments