Cannot widen from target type to primitive type.
By rickvdbosch
- 2 minutes read - 384 wordsA few days ago we ran into the error in the subject of this post at my current project. Because it wasn’t easy finding any usefull hints pointing towards a solution, I’ll post ours here.
We use reflection for flexible databinding, based on types and their attributes. One of the methods we wrote sets a value, passed in as an object, on a specific attribute of a specific class. The method knows nothing about the class and its properties. Not even which type the properties are.
We received the error on only 1 attribute, and only when setting its value. It was an sbyte property, which was bound to the SelectedIndex property of a ComboBox. The value passed in the method was a valid value: -1, 0 or 1. But on all possible values, we received the error. Eventually, after reading the QuickWatch in stead of watching it, I saw a small but important difference between the (type of) value I passed in and the (type of) value I wanted to set…
We implemented a GetValue on our controls to return the value, which was used in the method to write it to the object. Because we wanted to bind to the SelectedIndex, the GetValue of the combo we were binding against, looked a bit like this:
object returnValue;
returnValue = SelectedIndex – 1;
return returnValue;
See the problem? The GetValue returned an object, just the way my setter method wanted it. The value of my object was also valid: -1, 0 or 1. But the problem was not the value, neither the returntype of GetValue. The problem is a .NET object ‘knows’ what type you have put in. So it ‘knows’ what type it should get out….. (Sure, actually this goes a bit deeper, but for this high-level post, let’s leave it at this, OK?)
Because the (integer!) SelectedIndex was put in the returnValue object, the setter method tried to write an integer value to an sbyte property. And that doesn’t fit! The implicit cast used is not valid, which results in the above mentioned error. So although the value is correct, the type containing the value isn’t, and therefore it cannot be assigned to the sbyte property. Changing the GetValue method to put an sbyte into the object which was returned solved the problem.