我有一个List<Type>
代表来自自定义脚本语言的基于文本的命令的签名。我正在尝试确定如何将String[]
解析为List<object>
,其中对象类型与List<Type>
相关联。基本上给出Type t
我想尝试将String s
投射到Type
。
到目前为止,我有这个
Type t = ...;
String s = ...;
if(Convert.ChangeType(s, t) != null)
{
}
在考虑Convert.ChangeType
后,我怀疑是否正确。它只是简单地改变给定对象的类型,而不是“解析”它。看你不能简单地做(double)"ImAString"
我会假设这个方法将用于在“直接”可转换的对象类型之间进行转换。
这有什么一般解决方案吗?或者是唯一的方法是在给定的switch
上创建一个大Type
并在每种情况下进行解析(很可能在将来缺少切换中的类型)?
编辑:此外,ChangeType
的返回类型是对象。我假设如果我要做retObjectFromChange is double
将是真的(假设我将类型更改为double)?
答案 0 :(得分:2)
Convert.ChangeType()
会尽可能地将字符串解析为数字,在非有效数字的字符串上抛出异常。
注意:如果您要在自己的自定义类型之间进行大量转换,则可能需要使用TypeConverter
。 (TypeConverter
在将两者转换为原始类型(如string
时)时效果会更好。)
请参阅: Convert System.String generically to any complex type using "Convert.ChangeType()"
编辑:
是的,假设没有抛出异常,Convert.ChangeType("1.02", typeof(double)) is double
应评估为true。
答案 1 :(得分:2)
这是我目前的实施。我发现Guid,DateTime,enums和nullables是我的优势。我输入逻辑来处理空字符串和空值。我对一些原语进行了具体处理,因为我发现TypeConverter比较慢,并且它们是我的一般情况。
public object GetValue(string readerValue, Type conversionType)
{
// if the type is a string, just return the value with no conversion
if (conversionType == typeof(string) || conversionType == typeof(object))
{
return readerValue;
}
// if the field has a value try to cast it
if (!string.IsNullOrWhiteSpace(readerValue))
{
readerValue = readerValue.Trim();
if (conversionType.IsEnum)
{
return Enum.Parse(conversionType, readerValue);
}
else
{
Type underlyingType = Nullable.GetUnderlyingType(conversionType) ?? conversionType;
if (underlyingType == typeof(int))
{
return int.Parse(readerValue);
}
else if (underlyingType == typeof(bool))
{
return bool.Parse(readerValue);
}
else if (underlyingType == typeof(DateTime))
{
return DateTime.Parse(readerValue);
}
else if (underlyingType == typeof(double))
{
return double.Parse(readerValue);
}
else if (underlyingType == typeof(long))
{
return long.Parse(readerValue);
}
else if (underlyingType == typeof(Guid))
{
return Guid.Parse(readerValue);
}
else
{
// GetConverter and ConvertFrom are both slow, so only use it in a fallback
TypeConverter converter = TypeDescriptor.GetConverter(underlyingType);
return converter.ConvertFrom(readerValue);
}
}
}
// return null for nullable generic primitives
else if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return null;
}
// return the default value for non nullable primitive types
else if (conversionType.IsValueType)
{
return Activator.CreateInstance(conversionType);
}
// return null for reference types
else
{
return null;
}
}