使用“Convert.ChangeType()”将System.String一般转换为任何复杂类型

我尝试将用户输入一般转换为简单或复杂类型:

class Program { static void Main(string[] args) { Console.WriteLine("Welcome, please provide the following info... Confirm with !"); Console.WriteLine(); Console.Write("Name (eg 'Peggy Sue'): "); var user = GetUserInput(Console.ReadLine()); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Hi {0}, nice to meet you!", user.Forename); Console.WriteLine(); Console.Write("Age: "); user.Age = GetUserInput(Console.ReadLine()); Console.WriteLine(); Console.WriteLine("Thanks and goodbye!"); Console.WriteLine("Press  to quit..."); Console.ReadLine(); } static T GetUserInput(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; } } 

为了转换到我的“User”类,我总是得到exception“从’System.String’到’ConsoleApplication1.User’的无效转换。”。 有谁知道如何解决这一问题?

如果我尝试这样的东西(不是一般),它的工作就完美了:

 Console.WriteLine((string) ((User) "Peggy Sue")); 

这里的一个选项可能是将TypeConverter与您关注的类型相关联(您可以在编译时通过[TypeConverter(...)]执行此操作,或者如果您不控制,则可以在运行时执行此操作类型)。

然后它是:

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

不, Convert.ChangeType只适用于一组固定的类型,我相信……或者如果原始对象实现了IConvertible ,它可以调用IConvertible.ToType 。 这意味着您可以User类中实现IConvertible并具有

 Convert.ChangeType(user, typeof(string)) 

工作,但这不会相反。

您是否有需要转换的固定类型? 如果是这样,您可以使用转换委托填充的Dictionary> 。 然后你只需要调用适当的转换并转换返回值。 这很难看,但可能是你最好的选择。

我修好了它。 检查一下:

 class Program { static void Main(string[] args) { Console.WriteLine("Welcome, please provide the following info... Confirm with !"); Console.WriteLine(); Console.Write("Name (eg 'Peggy Sue'): "); var user = GetUserInput(Console.ReadLine()); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Hi {0}, nice to meet you!", user.Forename); Console.WriteLine(); Console.Write("Age: "); user.Age = GetUserInput(Console.ReadLine()); Console.WriteLine(); Console.WriteLine("Thanks and goodbye!"); Console.WriteLine("Press  to quit..."); Console.ReadLine(); } static T GetUserInput(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; } } 

如果你想转换为数字类型,我更喜欢更简洁和意图暴露:

 decimal.Parse(someString) 

或者,在您的示例中:

 new User(userName) 

没有理由创建一个完整的方法(或类,如果您决定将来“使这个可重用”)只是为了包装一个演员。 当语言已经采用不太透明的方式来表达代码的意图时,尤其如此。