PositiveGuy
PositiveGuy

Reputation: 47763

Nullable Enum cast to Int16

I keep getting the error System.InvalidCastException: Specified cast is not valid. during runtime. RewardJoinType could be null in the db.

This is the line of code where the cast fails:

c.rewardJoinType = (RewardJoinType)reader.GetInt16();

'reader.GetInt16()' threw an exception of type 'System.InvalidCastException' short {System.InvalidCastException}

In a class I've got the following lines of code:

private RewardJoinType? rewardJoinType; 

...some other code

c.rewardJoinType = (RewardJoinType?)reader.GetInt16();

...some other code

conn.AddParam("@rewardJoinType", (int?)rewardJoinType);

...some other code

public RewardJoinType? RewardJoinType
{
     get { return rewardJoinType; }
     set { rewardJoinType = value; }
}

And here's the enum itself

public enum RewardJoinType
{
    Auto,
    Manual
}

Is it because by default enum is Int32 and even though I've got it as nullable it's not able to cast a null Int16?

We handle DBNull for the Int16 like so already in our reader:

    public short GetInt16()
    {
        columnIndex++;
        return reader.IsDBNull(columnIndex) ? (short)0 : reader.GetInt16(columnIndex);
    }

Upvotes: 0

Views: 1688

Answers (3)

thecoop
thecoop

Reputation: 46128

When a database value is null, what you actually get back is an instance of DBNull, not 'null', and DBNull cannot be converted to anything else. What I do for these situations is write a helper method to convert the return value from GetXXX() into null or a nullable struct. Something like:

    static T? ConvertIfNotDBNull<T>(object o, Converter<object, T> converter) where T : struct {
        return o is DBNull ? (T?)null : converter(o);
    }

and you pass in Convert.ToInt32 or similar as the converter.

It could help if you run it with a debugger attached, find out exactly where it is throwing the exception, and then seeing what it is trying to cast to and from.

Upvotes: 5

PositiveGuy
PositiveGuy

Reputation: 47763

Ok, my mistake. The reader needed to be GetInt8() which translates in our code to returning a byte since the DB field is of type tinyInt

Upvotes: 1

chris holmok
chris holmok

Reputation: 1

Database nulls are not code nulls so you need something like this

obj val = reader.GetValue();
if(val != DbNull.Value) c.RewardJoinType = (RewardJoinType)val;

Upvotes: 0

Related Questions