Sebi
Sebi

Reputation: 3979

How to convert object to generic

If I get some values from the database in C#, they are type object. Now I want to convert this values typesafe to load them into my object which represents a datarow more or less. So I thought it would be nice to create a generic extend-method for extend object.

So I build the following:

public static T ConvertToType<T>(this object value)
{
    T returnValue = default(T);
    if (value != DBNull.Value)
    {
        returnValue = (T)value;
    }
      
    return returnValue;
}

So I can use this to convert the different values from the given datarow and if the database stores null value I get the default type.

For example:

foreach (DataRow row in myTable.Rows)
{
   MyClass myObject = new MyClass();
   myObject.Id = row["ID"].ConvertToType<int>();
}

This works for compile time but it seems not possible to cast object to int for example. So I thought all value types have to be handled manually.

So I extend the first Code-Block:

public static T ConvertToType<T>(this object value)
{
   T returnValue = default(T);
   if (value != DBNull.Value)
   {
      if (value is int)
      {
          returnValue = Convert.ToInt32(value);
      }
      //else if All Value-Types are following...
      else
      {
          returnValue = (T)value;
      }
   }
  
   return returnValue;
}

But for sure the compiler now tells me that target type T can't be converted to int. This is quite clear.

Is someone out there who got a well solution for this issue? Or is this not as simple as I hoped.

Upvotes: 5

Views: 5405

Answers (2)

anon
anon

Reputation: 192

Try this: Convert.ChangeType

public static T ConvertTo<T>(this object value)
    {
        T returnValue = default(T);

        if (value is T)
        {
            returnValue = (T)value;
        }
        else
        {
            try
            {
                returnValue = (T)Convert.ChangeType(value, typeof(T));
            }
            catch (InvalidCastException)
            {
                returnValue = default(T);
            }
        }

        return returnValue;
    }

Maybe you should think of not catching the InvalidCastException here. If you can imagine that the default type-value could be of some use in your program it could be better to let the calling method handle the exception.

Upvotes: 4

Steve
Steve

Reputation: 11963

This has already been implemented.

you can do row.Field<int>("ID")

the extension method is under System.Data namespace

for nullable fields, you can do row.Field<int?>("ID") since .Field returns null instead of default(T) for DBNull

Upvotes: 6

Related Questions