Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Casting from 'System.Int16' to type 'System.Int32'

I encountered an error saying that "Unable to cast object of type ‘System.Int16‘ to type ‘System.Int32‘." Isn’t it too unlogical? How come? When I try the following on immediate windows, the output as such that

reader.GetInt16(mycolumn_ordinal_value)
999
reader.GetInt32(mycolumn_ordinal_value)
Exception thrown: 'System.InvalidCastException' in Microsoft.Data.SqlClient.dll

At DB level (sqlserver), it is defined as mycolumn smallint.

When I ask it to Github Copilot it says literally,

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

However, when you try to use reader.GetInt32(mycolumn), it throws a
System.InvalidCastException. This is unusual(you can’t be serious bruh!!) because GetInt32
should be able to handle any value that GetInt16 can handle, since
the range of a 32-bit integer (-2,147,483,648 to 2,147,483,647) is
much larger.

I don’t understand it. Any idea?

>Solution :

This happens because when you call SqlDataReader.GetInt32() for a short it ends up internally calling code like return (Int32)this.Value where this.Value is a boxed short – which is where the exception arises.

We can look at the source for SqlDataReader.GetInt32():

override public Int32 GetInt32(int i) {
    ReadColumn(i);
    return _data[i].Int32;
}

That _data is an array of type SqlBuffer. The definition of SqlBuffer.Int32 is:

internal Int32 Int32 {
    get {
        ThrowIfNull();

        if (StorageType.Int32 == _type) {
            return _value._int32;
        }
        return (Int32)this.Value; // anything else we haven't thought of goes through boxing.
    }
}

The crucial thing here is that because the storage type doesn’t match, it returns (Int32)this.Value. In this case, this.Value is of type object, and is actually a boxed version of that actual underlying type – for your example that’s Int16.

Hence it’s trying to cast a boxed Int16 to an Int32 and it throws the exception.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading