title: How to (efficiently) convert (cast?) a SqlDataReader field to its corresponding c# type?
body: <p>First, let me explain the current situation: I'm reading records from a database and putting them in an object for later use; today a question about the database type to C# type conversion (casting?) arose.</p>
  
  <p>Let's see an example:</p>
  
  <pre><code>namespace Test
  {
      using System;
      using System.Data;
      using System.Data.SqlClient;
  
      public enum MyEnum
      {
          FirstValue = 1,
          SecondValue = 2
      }
  
      public class MyObject
      {
          private String field_a;
          private Byte field_b;
          private MyEnum field_c;
  
          public MyObject(Int32 object_id)
          {
              using (SqlConnection connection = new SqlConnection("connection_string"))
              {
                  connection.Open();
  
                  using (SqlCommand command = connection.CreateCommand())
                  {
                      command.CommandText = "sql_query";
  
                      using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow))
                      {
                          reader.Read();
  
                          this.field_a = reader["field_a"];
                          this.field_b = reader["field_b"];
                          this.field_c = reader["field_c"];
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>This is (obviously) failing because the three <code>this.field_x = reader["field_x"];</code> calls are throwing the <code>Cannot implicitly convert type 'object' to 'xxx'. An explicit conversion exists (are you missing a cast?).</code> compiler error.</p>
  
  <p>To correct this I <em>currently</em> know of two ways (let's use the <code>field_b</code> example): number one is <code>this.field_b = (Byte) reader["field_b"];</code> and number two is <code>this.field_b = Convert.ToByte(reader["field_b"]);</code>.</p>
  
  <p>The problem with option number one is that <code>DBNull</code> fields are throwing exceptions as the cast is failing (even with nullable types as <code>String</code>), ant the problem with number two is that it's not preserving null values (the <code>Convert.ToString(DBNull)</code> yields a <code>String.Empty</code>), and I can't use them with enums too.</p>
  
  <p>So, after a couple of lookups on the internet and here at StackOverflow, what I came up with is:</p>
  
  <pre><code>public static class Utilities
  {
      public static T FromDatabase&lt;T&gt;(Object value) where T: IConvertible
      {
          if (typeof(T).IsEnum == false)
          {
              if (value == null || Convert.IsDBNull(value) == true)
              {
                  return default(T);
              }
              else
              {
                  return (T) Convert.ChangeType(value, typeof(T));
              }
          }
          else
          {
              if (Enum.IsDefined(typeof(T), value) == false)
              {
                  throw new ArgumentOutOfRangeException();
              }
  
              return (T) Enum.ToObject(typeof(T), value);
          }
      }
  }
  </code></pre>
  
  <p>This way I <em>should</em> handle every case.</p>
  
  <p><strong>Question is:</strong> Am I missing something? Am I doing a WOMBAT (<em>Waste Of Money, Brain And Time</em>) as there's a quicker and cleaner way to do it? It's all correct? Profit?</p>