I'm sure I found inspiration for this somewhere around interweb, but I don't seem to be able to find the source anymore. In any case, below you will find a utility class that allows you to define the extension method in the DataReader, for example:
public static class DataReaderExtensions { public static TResult Get<TResult>(this IDataReader reader, string name) { return reader.Get<TResult>(reader.GetOrdinal(name)); } public static TResult Get<TResult>(this IDataReader reader, int c) { return ConvertTo<TResult>.From(reader[c]); } }
Using:
reader.Get<bool?>("columnname")
or
reader.Get<int?>(5)
Here is the inclusive utility class:
public static class ConvertTo<T> { // 'Factory method delegate', set in the static constructor public static readonly Func<object, T> From; static ConvertTo() { From = Create(typeof(T)); } private static Func<object, T> Create(Type type) { if (!type.IsValueType) { return ConvertRefType; } if (type.IsNullableType()) { return (Func<object, T>)Delegate.CreateDelegate(typeof(Func<object, T>), typeof(ConvertTo<T>).GetMethod("ConvertNullableValueType", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { type.GetGenericArguments()[0] })); } return ConvertValueType; } // ReSharper disable UnusedMember.Local // (used via reflection!) private static TElem? ConvertNullableValueType<TElem>(object value) where TElem : struct { if (DBNull.Value == value) { return null; } return (TElem)value; } // ReSharper restore UnusedMember.Local private static T ConvertRefType(object value) { if (DBNull.Value != value) { return (T)value; } return default(T); } private static T ConvertValueType(object value) { if (DBNull.Value == value) { throw new NullReferenceException("Value is DbNull"); } return (T)value; } }
EDIT: uses the IsNullableType () extension method, defined as follows:
public static bool IsNullableType(this Type type) { return (type.IsGenericType && !type.IsGenericTypeDefinition) && (typeof (Nullable<>) == type.GetGenericTypeDefinition()); }
jeroenh
source share