将字符串转换为可空类型(int, double,等等…)

时间:2022-03-12 22:28:15

I am attempting to do some data conversion. Unfortunately, much of the data is in strings, where it should be int's or double, etc...

我想做一些数据转换。不幸的是,很多数据都是字符串形式,应该是int或double等等。

So what I've got is something like:

所以我得到的是

double? amount = Convert.ToDouble(strAmount);

The problem with this approach is if strAmount is empty, if it's empty I want it to amount to be null, so when I add it into the database the column will be null. So I ended up writing this:

这种方法的问题是如果strAmount是空的,如果它是空的,我希望它等于null,所以当我将它添加到数据库中时,列将是空的。所以我最后写了这样一句话:

double? amount = null;
if(strAmount.Trim().Length>0)
{
    amount = Convert.ToDouble(strAmount);
}

Now this works fine, but I now have five lines of code instead of one. This makes things a little more difficult to read, especially when I have a large amount of columns to convert.

现在这很好,但是我现在有5行代码而不是1行。这使得阅读变得有点困难,尤其是当我要转换大量的列时。

I thought I'd use an extension to the string class and generic's to pass in the type, this is because it could be a double, or an int, or a long. So I tried this:

我想我应该使用字符串类和泛型类的扩展来传递类型,这是因为它可以是double, int,或者long。所以我试着:

    public static class GenericExtension
    {
        public static Nullable<T> ConvertToNullable<T>(this string s, T type) where T: struct
        {
            if (s.Trim().Length > 0)
            {
                return (Nullable<T>)s;
            }
            return null;
        }
    }

But I get the error: Cannot convert type 'string' to 'T?'

但我得到的错误是:不能将类型'string'转换为'T?'

Is there a way around this? I am not very familiar with creating methods using generics.

有办法解决这个问题吗?我不太熟悉使用泛型创建方法。

15 个解决方案

#1


143  

Another thing to keep in mind is that the string itself might be null.

另一件需要记住的事情是字符串本身可能是空的。

public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
    Nullable<T> result = new Nullable<T>();
    try
    {
        if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0)
        {
            TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
            result = (T)conv.ConvertFrom(s);
        }
    }
    catch { } 
    return result;
}

#2


47  

You could try using the below extension method:

您可以尝试使用以下扩展方法:

public static T? GetValueOrNull<T>(this string valueAsString)
    where T : struct 
{
    if (string.IsNullOrEmpty(valueAsString))
        return null;
    return (T) Convert.ChangeType(valueAsString, typeof(T));
}

This way you can do this:

这样你就可以做到:

double? amount = strAmount.GetValueOrNull<double>();
int? amount = strAmount.GetValueOrNull<int>();
decimal? amount = strAmount.GetValueOrNull<decimal>();

#3


22  

I wrote this generic type converter. It works with Nullable and standard values, converting between all convertible types - not just string. It handles all sorts of scenarios that you'd expect (default values, null values, other values, etc...)

我编写了这个泛型类型转换器。它使用可空值和标准值,在所有可转换类型之间进行转换,而不仅仅是字符串。它处理所有您期望的场景(默认值、空值、其他值等等…)

I've been using this for about a year in dozens of production programs, so it should be pretty solid.

我已经在几十个生产程序中使用这个工具一年了,所以它应该是非常可靠的。

    public static T To<T>(this IConvertible obj)
    {
        Type t = typeof(T);

        if (t.IsGenericType
            && (t.GetGenericTypeDefinition() == typeof(Nullable<>)))
        {
            if (obj == null)
            {
                return (T)(object)null;
            }
            else
            {
                return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(t));
            }
        }
        else
        {
            return (T)Convert.ChangeType(obj, t);
        }
    }

    public static T ToOrDefault<T>
                 (this IConvertible obj)
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return default(T);
        }
    }

    public static bool ToOrDefault<T>
                        (this IConvertible obj,
                         out T newObj)
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = default(T);
            return false;
        }
    }

    public static T ToOrOther<T>
                           (this IConvertible obj,
                           T other)
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return other;
        }
    }

    public static bool ToOrOther<T>
                             (this IConvertible obj,
                             out T newObj,
                             T other)
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = other;
            return false;
        }
    }

    public static T ToOrNull<T>
                          (this IConvertible obj)
                          where T : class
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return null;
        }
    }

    public static bool ToOrNull<T>
                      (this IConvertible obj,
                      out T newObj)
                      where T : class
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = null;
            return false;
        }
    }

#4


21  

What about this:

这个:


double? amount = string.IsNullOrEmpty(strAmount) ? (double?)null : Convert.ToDouble(strAmount);

Of course, this doesn't take into account the convert failing.

当然,这没有考虑到转换失败。

#5


8  

You might want to try:

你可能想试试:

TypeConverter conv = TypeDescriptor.GetConverter(typeof(int));
conv.ConvertFrom(mystring);

do your own null check and return int? if necessary. You'll also want to wrap that in a try {}

自己做空检查并返回int?如果有必要的话)。您还需要将其封装在try{}中

#6


6  

Give this a shot...

给这一枪…

public delegate bool TryParseDelegate<T>(string data, out T output);

public static T? ToNullablePrimitive<T>(this string data, 
    TryParseDelegate<T> func) where T:struct
{
    string.IsNullOrEmpty(data) return null;

    T output;

    if (func(data, out output))
    {
        return (T?)output;
    }

    return null;
}

Then call it like this...

然后这样称呼……

void doStuff()
{
    string foo = "1.0";

    double? myDouble = foo.ToNullablePrimitive<double>(double.TryParse);

    foo = "1";

    int? myInt = foo.ToNullablePrimitive<int>(int.TryParse);

    foo = "haha";

    int? myInt2 = foo.ToNullablePrimitive<int>(int.TryParse);
}

#7


5  

I like Joel's answer, but I've modified it slightly as I'm not a fan of eating exceptions.

我喜欢Joel的答案,但我稍微修改了一下,因为我不喜欢吃异常。

    /// <summary>
    /// Converts a string to the specified nullable type.
    /// </summary>
    /// <typeparam name="T">The type to convert to</typeparam>
    /// <param name="s">The string to convert</param>
    /// <returns>The nullable output</returns>
    public static T? ToNullable<T>(this string s) where T : struct
    {
        if (string.IsNullOrWhiteSpace(s))
            return null;

        TypeConverter conv = TypeDescriptor.GetConverter(typeof (T));
        return (T) conv.ConvertFrom(s);
    }

    /// <summary>
    /// Attempts to convert a string to the specified nullable primative.
    /// </summary>
    /// <typeparam name="T">The primitive type to convert to</typeparam>
    /// <param name="data">The string to convert</param>
    /// <param name="output">The nullable output</param>
    /// <returns>
    /// True if conversion is successfull, false otherwise.  Null and whitespace will
    /// be converted to null and return true.
    /// </returns>
    public static bool TryParseNullable<T>(this string data, out T? output) where T : struct
    {
        try
        {
            output = data.ToNullable<T>();
            return true;
        }
        catch
        {
            output = null;
            return false;
        }
    }

#8


5  

You can use the following with objects, unfortunately this does not work with strings though.

您可以对对象使用以下命令,但不幸的是,这不能对字符串起作用。

double? amount = (double?)someObject;

I use it for wrapping a session variable in a property (on a base page).. so my actual usage is (in my base page):

我使用它在属性(基页)中包装会话变量。所以我的实际用法是(在我的本页):

public int? OrganisationID
{
    get { return (int?)Session[Constants.Session_Key_OrganisationID]; }
    set { Session[Constants.Session_Key_OrganisationID] = value; }
}

I'm able to check for null in page logic:

我可以在页面逻辑中检查null:

if (base.OrganisationID == null)
    // do stuff

#9


3  

There is no way around this. Nullable, as well as your method, is constrained to using only value types as it's argument. String is a reference type and hence is incompatible with this declaration.

这是没有办法的。Nullable和您的方法被限制为仅使用值类型作为参数。String是一个引用类型,因此与此声明不兼容。

#10


3  

public static class GenericExtension
{
    public static T? ConvertToNullable<T>(this String s) where T : struct 
    {
        try
        {
            return (T?)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(s);
        }
        catch (Exception)
        {
            return null;
        }
    }
}

#11


3  

There is a generic solution (for any type). Usability is good, but implementation should be improved: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

有一个通用的解决方案(适用于任何类型)。可用性很好,但是实现应该改进:http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/。

This allows you to write very clean code like this:

这允许您编写非常干净的代码:

string value = null;
int? x = value.ConvertOrDefault<int?>();

and also:

还有:

object obj = 1;  

string value = null;
int x = 5;
if (value.TryConvert(out x))
    Console.WriteLine("TryConvert example: " + x); 

bool boolean = "false".ConvertOrDefault<bool>();
bool? nullableBoolean = "".ConvertOrDefault<bool?>();
int integer = obj.ConvertOrDefault<int>();
int negativeInteger = "-12123".ConvertOrDefault<int>();
int? nullableInteger = value.ConvertOrDefault<int?>();
MyEnum enumValue = "SecondValue".ConvertOrDefault<MyEnum>();

MyObjectBase myObject = new MyObjectClassA();
MyObjectClassA myObjectClassA = myObject.ConvertOrDefault<MyObjectClassA>();

#12


3  

Here's something based on accepted answer. I removed the try/catch to make sure all the exceptions are not swallowed and not dealt with. Also made sure that the return variable (in accepted answer) is never initialized twice for nothing.

这是基于公认的答案。我去掉了try/catch,以确保所有的异常都没有被吞咽,也没有被处理。还要确保返回变量(在可接受的答案中)不会因为没有任何原因而被初始化两次。

public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
    if (!string.IsNullOrWhiteSpace(s))
    {
        TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));

        return (T)conv.ConvertFrom(s);
    }

    return default(Nullable<T>);
}

#13


2  

My example for anonimous types:

我举了一个例子:

private object ConvertNullable(object value, Type nullableType)
{
    Type resultType = typeof(Nullable<>).MakeGenericType(nullableType.GetGenericArguments());
    return Activator.CreateInstance(resultType, Convert.ChangeType(value, nullableType.GetGenericArguments()[0]));
}

...

Type anonimousType = typeof(Nullable<int>);
object nullableInt1 = ConvertNullable("5", anonimousType);
// or evident Type
Nullable<int> nullableInt2 = (Nullable<int>)ConvertNullable("5", typeof(Nullable<int>));

#14


2  

Another variation. This one

另一个变化。这一个

  • Does not swallow exceptions
  • 不接受例外
  • Throws a NotSupportedException if the type can not be converted from string. For instance, a custom struct without a type converter.
  • 如果无法从字符串转换类型,则抛出NotSupportedException。例如,一个没有类型转换器的自定义结构。
  • Otherwise returns a (T?)null if the string fails to parse. No need to check for null or whitespace.
  • 否则,如果字符串无法解析,则返回(T?)null。不需要检查空或空格。
using System.ComponentModel;

public static Nullable<T> ToNullable<T>(this string s) where T : struct
{
    var ret = new Nullable<T>();
    var conv = TypeDescriptor.GetConverter(typeof(T));

    if (!conv.CanConvertFrom(typeof(string)))
    {
        throw new NotSupportedException();
    }

    if (conv.IsValid(s))
    {
        ret = (T)conv.ConvertFrom(s);
    }

    return ret;
}

#15


0  

Let's add one more similar solution to the stack. This one also parses enums, and it looks nice. Very safe.

让我们向堆栈添加一个类似的解决方案。这个也可以解析enums,看起来不错。非常安全。

/// <summary>
    /// <para>More convenient than using T.TryParse(string, out T). 
    /// Works with primitive types, structs, and enums.
    /// Tries to parse the string to an instance of the type specified.
    /// If the input cannot be parsed, null will be returned.
    /// </para>
    /// <para>
    /// If the value of the caller is null, null will be returned.
    /// So if you have "string s = null;" and then you try "s.ToNullable...",
    /// null will be returned. No null exception will be thrown. 
    /// </para>
    /// <author>Contributed by Taylor Love (Pangamma)</author>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="p_self"></param>
    /// <returns></returns>
    public static T? ToNullable<T>(this string p_self) where T : struct
    {
        if (!string.IsNullOrEmpty(p_self))
        {
            var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
            if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self);
            if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;}
        }

        return null;
    }

https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs

https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs

#1


143  

Another thing to keep in mind is that the string itself might be null.

另一件需要记住的事情是字符串本身可能是空的。

public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
    Nullable<T> result = new Nullable<T>();
    try
    {
        if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0)
        {
            TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
            result = (T)conv.ConvertFrom(s);
        }
    }
    catch { } 
    return result;
}

#2


47  

You could try using the below extension method:

您可以尝试使用以下扩展方法:

public static T? GetValueOrNull<T>(this string valueAsString)
    where T : struct 
{
    if (string.IsNullOrEmpty(valueAsString))
        return null;
    return (T) Convert.ChangeType(valueAsString, typeof(T));
}

This way you can do this:

这样你就可以做到:

double? amount = strAmount.GetValueOrNull<double>();
int? amount = strAmount.GetValueOrNull<int>();
decimal? amount = strAmount.GetValueOrNull<decimal>();

#3


22  

I wrote this generic type converter. It works with Nullable and standard values, converting between all convertible types - not just string. It handles all sorts of scenarios that you'd expect (default values, null values, other values, etc...)

我编写了这个泛型类型转换器。它使用可空值和标准值,在所有可转换类型之间进行转换,而不仅仅是字符串。它处理所有您期望的场景(默认值、空值、其他值等等…)

I've been using this for about a year in dozens of production programs, so it should be pretty solid.

我已经在几十个生产程序中使用这个工具一年了,所以它应该是非常可靠的。

    public static T To<T>(this IConvertible obj)
    {
        Type t = typeof(T);

        if (t.IsGenericType
            && (t.GetGenericTypeDefinition() == typeof(Nullable<>)))
        {
            if (obj == null)
            {
                return (T)(object)null;
            }
            else
            {
                return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(t));
            }
        }
        else
        {
            return (T)Convert.ChangeType(obj, t);
        }
    }

    public static T ToOrDefault<T>
                 (this IConvertible obj)
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return default(T);
        }
    }

    public static bool ToOrDefault<T>
                        (this IConvertible obj,
                         out T newObj)
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = default(T);
            return false;
        }
    }

    public static T ToOrOther<T>
                           (this IConvertible obj,
                           T other)
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return other;
        }
    }

    public static bool ToOrOther<T>
                             (this IConvertible obj,
                             out T newObj,
                             T other)
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = other;
            return false;
        }
    }

    public static T ToOrNull<T>
                          (this IConvertible obj)
                          where T : class
    {
        try
        {
            return To<T>(obj);
        }
        catch
        {
            return null;
        }
    }

    public static bool ToOrNull<T>
                      (this IConvertible obj,
                      out T newObj)
                      where T : class
    {
        try
        {
            newObj = To<T>(obj);
            return true;
        }
        catch
        {
            newObj = null;
            return false;
        }
    }

#4


21  

What about this:

这个:


double? amount = string.IsNullOrEmpty(strAmount) ? (double?)null : Convert.ToDouble(strAmount);

Of course, this doesn't take into account the convert failing.

当然,这没有考虑到转换失败。

#5


8  

You might want to try:

你可能想试试:

TypeConverter conv = TypeDescriptor.GetConverter(typeof(int));
conv.ConvertFrom(mystring);

do your own null check and return int? if necessary. You'll also want to wrap that in a try {}

自己做空检查并返回int?如果有必要的话)。您还需要将其封装在try{}中

#6


6  

Give this a shot...

给这一枪…

public delegate bool TryParseDelegate<T>(string data, out T output);

public static T? ToNullablePrimitive<T>(this string data, 
    TryParseDelegate<T> func) where T:struct
{
    string.IsNullOrEmpty(data) return null;

    T output;

    if (func(data, out output))
    {
        return (T?)output;
    }

    return null;
}

Then call it like this...

然后这样称呼……

void doStuff()
{
    string foo = "1.0";

    double? myDouble = foo.ToNullablePrimitive<double>(double.TryParse);

    foo = "1";

    int? myInt = foo.ToNullablePrimitive<int>(int.TryParse);

    foo = "haha";

    int? myInt2 = foo.ToNullablePrimitive<int>(int.TryParse);
}

#7


5  

I like Joel's answer, but I've modified it slightly as I'm not a fan of eating exceptions.

我喜欢Joel的答案,但我稍微修改了一下,因为我不喜欢吃异常。

    /// <summary>
    /// Converts a string to the specified nullable type.
    /// </summary>
    /// <typeparam name="T">The type to convert to</typeparam>
    /// <param name="s">The string to convert</param>
    /// <returns>The nullable output</returns>
    public static T? ToNullable<T>(this string s) where T : struct
    {
        if (string.IsNullOrWhiteSpace(s))
            return null;

        TypeConverter conv = TypeDescriptor.GetConverter(typeof (T));
        return (T) conv.ConvertFrom(s);
    }

    /// <summary>
    /// Attempts to convert a string to the specified nullable primative.
    /// </summary>
    /// <typeparam name="T">The primitive type to convert to</typeparam>
    /// <param name="data">The string to convert</param>
    /// <param name="output">The nullable output</param>
    /// <returns>
    /// True if conversion is successfull, false otherwise.  Null and whitespace will
    /// be converted to null and return true.
    /// </returns>
    public static bool TryParseNullable<T>(this string data, out T? output) where T : struct
    {
        try
        {
            output = data.ToNullable<T>();
            return true;
        }
        catch
        {
            output = null;
            return false;
        }
    }

#8


5  

You can use the following with objects, unfortunately this does not work with strings though.

您可以对对象使用以下命令,但不幸的是,这不能对字符串起作用。

double? amount = (double?)someObject;

I use it for wrapping a session variable in a property (on a base page).. so my actual usage is (in my base page):

我使用它在属性(基页)中包装会话变量。所以我的实际用法是(在我的本页):

public int? OrganisationID
{
    get { return (int?)Session[Constants.Session_Key_OrganisationID]; }
    set { Session[Constants.Session_Key_OrganisationID] = value; }
}

I'm able to check for null in page logic:

我可以在页面逻辑中检查null:

if (base.OrganisationID == null)
    // do stuff

#9


3  

There is no way around this. Nullable, as well as your method, is constrained to using only value types as it's argument. String is a reference type and hence is incompatible with this declaration.

这是没有办法的。Nullable和您的方法被限制为仅使用值类型作为参数。String是一个引用类型,因此与此声明不兼容。

#10


3  

public static class GenericExtension
{
    public static T? ConvertToNullable<T>(this String s) where T : struct 
    {
        try
        {
            return (T?)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(s);
        }
        catch (Exception)
        {
            return null;
        }
    }
}

#11


3  

There is a generic solution (for any type). Usability is good, but implementation should be improved: http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/

有一个通用的解决方案(适用于任何类型)。可用性很好,但是实现应该改进:http://cleansharp.de/wordpress/2011/05/generischer-typeconverter/。

This allows you to write very clean code like this:

这允许您编写非常干净的代码:

string value = null;
int? x = value.ConvertOrDefault<int?>();

and also:

还有:

object obj = 1;  

string value = null;
int x = 5;
if (value.TryConvert(out x))
    Console.WriteLine("TryConvert example: " + x); 

bool boolean = "false".ConvertOrDefault<bool>();
bool? nullableBoolean = "".ConvertOrDefault<bool?>();
int integer = obj.ConvertOrDefault<int>();
int negativeInteger = "-12123".ConvertOrDefault<int>();
int? nullableInteger = value.ConvertOrDefault<int?>();
MyEnum enumValue = "SecondValue".ConvertOrDefault<MyEnum>();

MyObjectBase myObject = new MyObjectClassA();
MyObjectClassA myObjectClassA = myObject.ConvertOrDefault<MyObjectClassA>();

#12


3  

Here's something based on accepted answer. I removed the try/catch to make sure all the exceptions are not swallowed and not dealt with. Also made sure that the return variable (in accepted answer) is never initialized twice for nothing.

这是基于公认的答案。我去掉了try/catch,以确保所有的异常都没有被吞咽,也没有被处理。还要确保返回变量(在可接受的答案中)不会因为没有任何原因而被初始化两次。

public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
    if (!string.IsNullOrWhiteSpace(s))
    {
        TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));

        return (T)conv.ConvertFrom(s);
    }

    return default(Nullable<T>);
}

#13


2  

My example for anonimous types:

我举了一个例子:

private object ConvertNullable(object value, Type nullableType)
{
    Type resultType = typeof(Nullable<>).MakeGenericType(nullableType.GetGenericArguments());
    return Activator.CreateInstance(resultType, Convert.ChangeType(value, nullableType.GetGenericArguments()[0]));
}

...

Type anonimousType = typeof(Nullable<int>);
object nullableInt1 = ConvertNullable("5", anonimousType);
// or evident Type
Nullable<int> nullableInt2 = (Nullable<int>)ConvertNullable("5", typeof(Nullable<int>));

#14


2  

Another variation. This one

另一个变化。这一个

  • Does not swallow exceptions
  • 不接受例外
  • Throws a NotSupportedException if the type can not be converted from string. For instance, a custom struct without a type converter.
  • 如果无法从字符串转换类型,则抛出NotSupportedException。例如,一个没有类型转换器的自定义结构。
  • Otherwise returns a (T?)null if the string fails to parse. No need to check for null or whitespace.
  • 否则,如果字符串无法解析,则返回(T?)null。不需要检查空或空格。
using System.ComponentModel;

public static Nullable<T> ToNullable<T>(this string s) where T : struct
{
    var ret = new Nullable<T>();
    var conv = TypeDescriptor.GetConverter(typeof(T));

    if (!conv.CanConvertFrom(typeof(string)))
    {
        throw new NotSupportedException();
    }

    if (conv.IsValid(s))
    {
        ret = (T)conv.ConvertFrom(s);
    }

    return ret;
}

#15


0  

Let's add one more similar solution to the stack. This one also parses enums, and it looks nice. Very safe.

让我们向堆栈添加一个类似的解决方案。这个也可以解析enums,看起来不错。非常安全。

/// <summary>
    /// <para>More convenient than using T.TryParse(string, out T). 
    /// Works with primitive types, structs, and enums.
    /// Tries to parse the string to an instance of the type specified.
    /// If the input cannot be parsed, null will be returned.
    /// </para>
    /// <para>
    /// If the value of the caller is null, null will be returned.
    /// So if you have "string s = null;" and then you try "s.ToNullable...",
    /// null will be returned. No null exception will be thrown. 
    /// </para>
    /// <author>Contributed by Taylor Love (Pangamma)</author>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="p_self"></param>
    /// <returns></returns>
    public static T? ToNullable<T>(this string p_self) where T : struct
    {
        if (!string.IsNullOrEmpty(p_self))
        {
            var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
            if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self);
            if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;}
        }

        return null;
    }

https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs

https://github.com/Pangamma/PangammaUtilities-CSharp/blob/master/PangammaUtilities/Extensions/ToNullableStringExtension.cs