Hi.
I have this method:
public static TVal DoIT<TVal>(object value){
return (TVal)Convert.ChangeType(value, typeof(TVal));
}
But it fails in case of DoIt<DateTime >(DateTime.Now). (Invalid cast from 'System.DateTime' to 'System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.)
How can I make it working
I was trying to catch that case myself (happy with typeof(TVal).IsNullable), but I'm not able to create required nullable type because no constructor I found takes a System.Type (which I can get using Nullable.GetUnderlyingType)...

Casting to nullable generics
pecasis
Yes, I need Nullable<T> but with T taken form the generic, which is not supported as far as I have seen.
So this cannot be solved in C# 2 I cannot convert a struct into its nullable representation without knowing the struct at design time
david.r.johnson
Yes, I agree, that's fine. The problem is with values, which are not null.
So the question (from my point of view) is, how can I create an instance of Nullable type with the Type specified
man_25
Anyway, what I mean to say is you can do it this way (You may want to add more specializing and possibly checks for DBNull and whatnot, but this does what you were trying to do):
namespace Example {
using System;
internal class ValueConverter<T> {
internal static readonly ValueConverter<T> Instance = Initialize();
private static ValueConverter<T> Initialize() {
Type type = typeof(T);
Type underlyingType = Nullable.GetUnderlyingType(type);
if(underlyingType != null) {
// if T is nullable, use reflection to create an instance of NullableValueConverter
Type converterType = typeof(NullableValueConverter<>);
converterType = converterType.MakeGenericType(underlyingType);
return (ValueConverter<T>)Activator.CreateInstance(converterType);
}
else {
// otherwise use a normal converter
return new ValueConverter<T>();
}
}
internal ValueConverter() { }
internal virtual T ConvertValue(object value) {
return (T)Convert.ChangeType(value, typeof(T));
}
}
internal class NullableValueConverter<T> : ValueConverter<T > where T : struct {
public NullableValueConverter() : base() { }
internal override T ConvertValue(object value) {
if(value == null)
return null;
return (T)Convert.ChangeType(value, typeof(T));
}
}
class Program {
public static T ConvertValue<T>(object value) {
return ValueConverter<T>.Instance.ConvertValue(value);
}
static void Main(string[] args) {
Console.WriteLine(ConvertValue<DateTime >(null));
Console.WriteLine(ConvertValue<DateTime >(DateTime.Now));
Console.WriteLine(ConvertValue<DateTime >(DateTime.Now.ToString()));
Console.WriteLine(ConvertValue<DateTime>(DateTime.Now.ToString()));
}
}
}
Javier Canones
Adam_W
yashpal singh
Hello
If you have problems with a Datareaders you should take a look at the "safeDatareader" from CSLA from Rocky Lhotka. Its a Datareader that will avoid all the NULL hassle you get if you know that you dont have to really care about NULLs. It is included in its CSLA code which you can download from its website... The datareader works exactly like a normal one with the only difference that it handels NULLs transperently. Also it supports the full datareader interface so it can be used exactly like the normal one... And while we are at the topic of NULL in DBs and .NET you should also look at the smartdate class
Take a look at this site
http://www.lhotka.net/
Hope this helps...
P.s. If you NEED to handle NULLs then just use the "plain" datareader
Gautam Goenka
IdahoErick
However, if for whatever reason the value doesn't match the type you're casitng to you get null. This could be a problem if you're targeting multiple database platforms, but otherwise I rarely have trouble with it. When using a DataReader, however, I like to have a wrapper class that has methods returning nullable values instead.
// nullables
DateTime updateDate = dataRow["UpdateDate"] as DateTime ;
int contactId = dataRow["ContactId"] as int ;
// non-nullables
bool flagged = dataRow["Flagged"] as bool false;
Kay Chan
Hi.. thank you, very nice example...
but I think I would stay at my frequently called helper function
public
static TVal FromDB<TVal>(object value){
TVal r = default(TVal);
if (value != DBNull.Value)
{
r = (TVal)Convert.ChangeType(value, typeof(TVal));
}
return r;
}
and check for the DBNull.Value explicitly myself without that function, when casting tu nullable type.
Please go ahead and vote for http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx feedbackid=1af9f75d-e566-41ff-ae00-84729ef8469e !
Bertrand JURADO
Dear miloush,
change into "DoIt<DateTime>(DateTime.Now);"
LondonSte
then you should try to check if the value is null.
because Convert.ChangeType(Object, Type) this method does not support null to pass in.
MSDN:
Parameters
An Object that implements the IConvertible interface.
Inkyskin_UK
Nope.
The thing is, that if value is null, it should return null.
j42
Hi,
thanks for the code, I've looked into it, but I need to handle NULLs because I'm casting to nullable types.
The DataReader that will do well with nullable types can be written that way of course, but this is a little off-topic, since the problem I'm presenting here is (as it seems to me) that the nullable types does not have constructors.