[英]Convert System.String generically to any complex type using “Convert.ChangeType()”
我尝试将用户输入一般转换为简单或复杂类型:
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; }
}
为了转换到我的“User”类,我总是得到异常“从'System.String'到'ConsoleApplication1.User'的无效转换。”。 有谁知道如何解决这一问题?
如果我尝试这样的东西(不是一般),它的工作就完美了:
Console.WriteLine((string) ((User) "Peggy Sue"));
不, Convert.ChangeType
只适用于一组固定的类型,我相信......或者如果原始对象实现了IConvertible
,它可以调用IConvertible.ToType
。 这意味着您可以在User
类中实现IConvertible
并具有
Convert.ChangeType(user, typeof(string))
工作,但这不会相反。
您是否有需要转换的固定类型? 如果是这样,您可以使用转换委托填充的Dictionary<Type, Func<string, object>>
。 然后你只需要调用适当的转换并转换返回值。 这很难看,但可能是你最好的选择。
这里的一个选项可能是将TypeConverter与您关注的类型相关联(您可以在编译时通过[TypeConverter(...)]
执行此操作,或者如果您不控制,则可以在运行时执行此操作类型)。
然后它是:
TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
T obj = (T)conv.ConvertFromString(text); // or ConvertFromInvariantString
我修好了它。 检查一下:
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;
}
}
如果你想转换为数字类型,我更喜欢更简洁和意图暴露:
decimal.Parse(someString)
或者,在您的示例中:
new User(userName)
没有理由创建一个完整的方法(或类,如果你决定将来“使这个可重用”)只是为了包装一个演员。 当语言已经采用不太透明的方式来表达代码的意图时,尤其如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.