Convert System.String to a generic type of any complex type using "Convert.ChangeType ()"

I am trying to convert user input to simple or complex types:

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Welcome, please provide the following info... Confirm with <RETURN>!");
    Console.WriteLine();    

    Console.Write("Name (e.g. 'Peggy Sue'): ");
    var user = GetUserInput<User>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine("Hi {0}, nice to meet you!", user.Forename);
    Console.WriteLine();

    Console.Write("Age: ");
    user.Age = GetUserInput<ushort>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine("Thanks and goodbye!");
    Console.WriteLine("Press <RETURN> to quit...");
    Console.ReadLine();
  }

  static T GetUserInput<T>(string data)
  {
    return (T) Convert.ChangeType(data, typeof (T));
  }
}

class User
{
  public User(string name)
  {
    var splitted = name.Split(' ');
    Forename = splitted[0];
    Lastname = splitted[1];
  }

  public static implicit operator User (string value)
  {
    return new User(value);
  }

  public static explicit operator string (User value)
  {
    return string.Concat(value.Forename, " ", value.Lastname);
  }

  public string Forename { get; private set; }
  public string Lastname { get; private set; }

  public ushort Age { get; set; }
}

To convert to my User class, I always get the exception "Invalid listing from" System.String "to" ConsoleApplication1.User ".". Does anyone know how to fix this?

If I try something like this (not in general), it works just fine:

Console.WriteLine((string) ((User) "Peggy Sue"));
+5
source share
4 answers

, TypeConverter , ( [TypeConverter(...)], , ).

:

TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
T obj = (T)conv.ConvertFromString(text); // or ConvertFromInvariantString
+5

, Convert.ChangeType , ... IConvertible, IConvertible.ToType. , IConvertible User

Convert.ChangeType(user, typeof(string))

, .

, ? , Dictionary<Type, Func<string, object>>, . . , , , .

+6

. :

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Welcome, please provide the following info... Confirm with <RETURN>!");
    Console.WriteLine();

    Console.Write("Name (e.g. 'Peggy Sue'): ");
    var user = GetUserInput<User>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine("Hi {0}, nice to meet you!", user.Forename);
    Console.WriteLine();

    Console.Write("Age: ");
    user.Age = GetUserInput<ushort>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine("Thanks and goodbye!");
    Console.WriteLine("Press <RETURN> to quit...");
    Console.ReadLine();
  }

  static T GetUserInput<T>(string data)
  {
    TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
    return (T) conv.ConvertFromInvariantString(data);
  }
}

[TypeConverter(typeof(UserConverter))]
class User
{
  public User(string name)
  {
    var splitted = name.Split(' ');
    Forename = splitted[0];
    Lastname = splitted[1];
  }

  public static explicit operator User (string value)
  {
    return new User(value);
  }

  public static explicit operator string (User value)
  {
    return string.Concat(value.Forename, " ", value.Lastname);
  }

  public string Forename { get; private set; }
  public string Lastname { get; private set; }

  public ushort Age { get; set; }
}

class UserConverter : TypeConverter
{
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
    return (typeof(string) == sourceType);
  }

  public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
  {
    if (value is string)
    {
      return (User)(value as string);
    }

    return null;
  }
}
+2

, :

decimal.Parse(someString)

:

new User(userName)

( , " " ), . , .

0

All Articles