1

I would like to create a function that has as input a string and return the converted string according to the T type.

I tried with

static T convertStringTemplate<T>(string myString)
        {
            return T.Parse(myString);
        }

However it does not work. Do you have any idea?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62

3 Answers3

1

Generics don't work like that. Generics have to be instantiable for any T that matches the constraints (no limits in your case). convertStringTemplate<object> is a simple example that would pretty obviously not work.

You write in a comment:

T can be any numeric type ( int, float, double,...)

If it only has to work for numeric types, then it's much simpler. Just call Convert.ChangeType.

  • I tried with `return Convert.ChangeType(myString, typeof(T));` however typeof does not recognize T –  Jun 10 '17 at 11:00
  • @GVa Either you're misreading the error message (`Convert.ChangeType` returns `object`, which you can then cast to `T`, but if this is the problem, it's not about `typeof`), or you've not put it in a generic method with a generic type parameter named `T`. –  Jun 10 '17 at 11:03
0

An easy way is to use the IConvertible interface:

static T ConvertStringTemplate<T>(string myString, IFormatProvider formatProvider = null)
{
    formatProvider = formatProvider ?? System.Globalization.CultureInfo.CurrentCulture;
    return (T)((IConvertible)myString).ToType(typeof(T), formatProvider);
}

If you want to restrict T to a numeric type, the closest constraint you may use is the following one (from this answer ):

static T ConvertStringTemplate<T>(string myString, IFormatProvider formatProvider = null)
    where T :
        struct, 
        IComparable, 
        IComparable<T>, 
        IConvertible, 
        IEquatable<T>, 
        IFormattable
{
    formatProvider = formatProvider ?? System.Globalization.CultureInfo.CurrentCulture;
    return (T)((IConvertible)myString).ToType(typeof(T), formatProvider);
}

Usage:

var x = ConvertStringTemplate<int>("12"); // results in 12

[Edit]
As stated in comments, you probably wanted to use the current culture while converting the string, so I added an IFormatProvider custom parameter to the method.

Federico Dipuma
  • 17,655
  • 4
  • 39
  • 56
  • Heh, the `IConvertible` interface is exactly what `Convert.ChangeType` (which I suggested in my answer) would end up using anyway. You may want to avoid `InvariantCulture`. The OP attempted to call `T.Parse`, which if it worked would perform a culture-sensitive parse. –  Jun 10 '17 at 10:52
  • @hvd Didn't know `Convert.ChangeType` used the `IConvertible` interface internally. Thanks for the clarification. – Federico Dipuma Jun 10 '17 at 10:57
  • This will blow up at runtime. – Kenneth K. Jun 10 '17 at 12:08
  • @KennethK. What should blow up? [DotNetFiddle here](https://dotnetfiddle.net/ugMd26) – Federico Dipuma Jun 10 '17 at 12:12
-1

Creating an instance of a type whose name is specified, using the named assembly and default constructor, can be done with Activator.CreateInstance Method (String, String)

Emiel Koning
  • 4,039
  • 1
  • 16
  • 18