开发者

Is there any generic Parse() function that will convert a string to any type using parse?

I want to conve开发者_StackOverflow中文版rt a string to a generic type like int or date or long based on the generic return type.

Basically a function like Parse<T>(String) that returns an item of type T.

For example if a int was passed the function should do int.parse internally.


System.Convert.ChangeType

As per your example, you could do:

int i = (int)Convert.ChangeType("123", typeof(int));
DateTime dt = (DateTime)Convert.ChangeType("2009/12/12", typeof(DateTime));

To satisfy your "generic return type" requirement, you could write your own extension method:

public static T ChangeType<T>(this object obj)
{
    return (T)Convert.ChangeType(obj, typeof(T));
}

This will allow you to do:

int i = "123".ChangeType<int>();


Well looks like I am too late for answering on this thread. But here is my implementation:

Basically, I have created an Extention method for the Object class. It handles all the types, i.e nullable, classes, and struct.

 public static T ConvertTo<T>(this object value)
           {
               T returnValue;

               if (value is T variable)
                   returnValue = variable;
               else
                   try
                   {
                       //Handling Nullable types i.e, int?, double?, bool? .. etc
                       if (Nullable.GetUnderlyingType(typeof(T)) != null)
                       {
                           TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
                           returnValue = (T) conv.ConvertFrom(value);
                       }
                       else
                       {
                           returnValue = (T) Convert.ChangeType(value, typeof(T));
                       }
                   }
                   catch (Exception)
                   {
                       returnValue = default(T);
                   }

               return returnValue;
           }


cleaner version of Pranay's answer

public static T ConvertTo<T>(this object value)
{
    if (value is T variable) return variable;

    try
    {
        //Handling Nullable types i.e, int?, double?, bool? .. etc
        if (Nullable.GetUnderlyingType(typeof(T)) != null)
        {
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFrom(value);
        }

        return (T)Convert.ChangeType(value, typeof(T));
    }
    catch (Exception)
    {
        return default(T);
    }
}


System.Convert.ChangeType does not convert to any type. Think of the following:

  • nullable types
  • enums
  • Guid etc.

These conversions are possible with this implementation of ChangeType.


There are a couple of conventions in the .NET to convert objects of one type to another.

  • Convert.ChangeType if the type implements IConvertible
  • TypeDescriptor.GetConverter if the type has a TypeConverterAttribute

But these methods are much slower than your typical T.Parse(string), cause boxing and involve lots of allocations each time you want to convert a single value.

For ValueString, I chose to find a suitable, static parsing method of the type using reflection, build a lambda expression calling it and cache the compiled delegate for future use (See this answer for an example).

It also fallbacks to the ways I mentioned above if the type doesn't have a suitable parsing method (See the performance section in the readme).

var v = new ValueString("15"); // struct
var i = v.As<int>(); // Calls int.Parse.


As of C# 11 and .Net 7, this is now possible and supported thanks to static methods on interfaces.

The new IParsable<TSelf> provides a static Parse method:

abstract static TSelf Parse(string s, IFormatProvider? provider);

All the common value types (int, decimal, Guid, etc) implement this interface, but with one exception: Nullable<T> doesn't, as obviously the T in nullable cannot be assumed to implement IParsable<T>. But this shouldn't be an issue in practice (example provided below).

Here's a simple extension method to make use of it:

public static T Parse<T>(this string s, IFormatProvider? provider = null) where T : IParsable<T>
{
    return T.Parse(s, provider);
}

So, for example, a call of myString.Parse<int> will directly call int.Parse without boxing, or the need for checking the type at runtime.

Example usage:

string s = "5";
int i = s.Parse<int>();
double d = s.Parse<double>();

// Need Nullable<T> support? Just use the null-conditional operator.
string? s2 = null;
decimal? d2 = s2?.Parse<decimal>();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜