tags:

views:

122

answers:

3

hi, I have a method (see below)

    public T ExecuteScalar<T>(string sSql, params SqlParameter[] parameters)
    {
        if (!string.IsNullOrEmpty(sSql))
        {
            DataAccess dal = new DataAccess(ConnectionString);
            DebugOutput_SQL(sSql, parameters);
            object value = null;
            value = dal.ExecuteScalar(sSql, parameters);

            if (value != null && value != DBNull.Value)
                return (T)value;
        }
        return default(T);
    }

and I call this

 int32 WorkFlowID = DataProvider.ExecuteScalar<Int32>(sSql);

then it give me a error "Don't unbox to value" in line "return (T)value", any suggestion for this.

+3  A: 

"Don't unbox to value" sounds like an odd error message. Is that exactly what it said?

My guess is that ExecuteScalar was returning a different type (long, double etc) rather than int. Try logging value.GetType() before you convert to T.

Just as a side-note, this:

object value = null;
value = dal.ExecuteScalar(sSql, parameters);

would be simpler (IMO) as:

object value = dal.ExecuteScalar(sSql, parameters);

There's no need to put it in two statements here.

EDIT: Just to clarify, the reason it's failing is that when you unbox a value, you have to unbox to the actual type, not just one which has a conversion available. For example, if you want to get an int out eventually, you could do:

int x = (int) (decimal) value;

which would unbox to decimal and then convert the decimal to an int. In this case though, I'd just specify the right type to start with if possible :)

Jon Skeet
Thanks Jon, you are right, I checked value that is decimal type.
leo
@Jon - I'm pretty sure your reasoning is right, but it's probably worth putting in an explanation that value types will only be unboxed to the exact type specified (e.g. you cannot unbox an int into a long even though the type conversion is implicit).
Greg Beech
@Greg: Good call. Will edit.
Jon Skeet
A: 

Maybe the value object that you receive is a Nullable in which case you could do

return ((Nullable<T>)value).Value;
DonAndre
+1  A: 

You could try:

public T ExecuteScalar<T>(string sSql, params SqlParameter[] parameters)
{
    if (!string.IsNullOrEmpty(sSql))
    {
        DataAccess dal = new DataAccess(ConnectionString);
        DebugOutput_SQL(sSql, parameters);
        object value = null;
        value = dal.ExecuteScalar(sSql, parameters);

        if (value != null && value != DBNull.Value)
            return (T) Convert.ChangeType(value, typeof(T));
    }
    return default(T);
}
leppie