简体   繁体   中英

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);
    }

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.

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM