I have created an extension function, which takes the string as input and check for the value and based on the Generic Type, cast it to the destination type and return it, it's working well.
Now the problem is if i pass the input value as empty it should return null, for nullable types, but it simply throws exception.
For e.g.: if i want to cast it to datetime, it throws below exception:
String was not recognized as a valid DateTime
Below is my code:
public static class Extension
{
public static T ToNull<T>(this string value)
{
var stringType = "System.Nullable`1[[System.{0}, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]";
if (typeof(T) == typeof(String))
stringType = string.Format(stringType, "String");
if (typeof(T) == typeof(Int32?) || typeof(T) == typeof(Int32))
stringType = string.Format(stringType, "Int32");
if (typeof(T) == typeof(DateTime?) || typeof(T) == typeof(DateTime))
stringType = string.Format(stringType, "DateTime");
if (typeof(T) == typeof(Int64?) || typeof(T) == typeof(Int64))
stringType = string.Format(stringType, "Int64");
Type originalType = Type.GetType(stringType);
var underlyingType = Nullable.GetUnderlyingType(originalType);
return (T)Convert.ChangeType(value, underlyingType ?? originalType);
}
}
and here how i am accessing it:
string s = "";
DateTime? t = s.ToNull<DateTime?>();
Console.WriteLine(t);
For above case i want to return null.
Below is the error that a generic method will throw if we are trying to return null. So, to return a null or default value from a generic method we can make use default (). default (T) will return the default object of the type which is provided. Here we could see that the default value of integer 0 is returned.
Return default (T) which means you'll return null if T is a reference type (or a nullable value type), 0 for int, '0' for char, etc. (Default values table (C# Reference)) Restrict T to be a reference type with the where T : class constraint and then return null as normal
Generics is the idea to allow type (Integer, String, … etc and user-defined types) to be a parameter to methods, classes and interfaces. For example, classes like an array, map, etc, which can be used using generics very efficiently.
You should (with a few modifications) be able to use the generic type instead: Since it rarely makes sense to check value types for null, you could also restrict it to reference types only. You will have to cast the result of CreateInstance before returning.
Then just return default
value
//Check for empty or null first
if(string.IsNullOrEmpty(value)) return default(T);
//Then your code
var stringType = "System.Nullable`1[[System.{0}, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]";
...
To answer @mjwills reply about creating separate methods, i found a solution to keep it single method and still handle any types you throw to it, dynamically.
public static class Extension
{
public static T ToNull<T>(this string value)
{
if (String.IsNullOrEmpty(value)) return default(T);
Type originalType = typeof(T);
var underlyingType = Nullable.GetUnderlyingType(originalType);
return (T)Convert.ChangeType(value, underlyingType ?? originalType);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With