通过将所需类型作为参数传递,从字符串值转换为特定类型

时间:2014-04-22 09:49:09

标签: c#-4.0 generics types type-conversion

我使用以下方法将字符串类型转换为泛型类型

public static T Parse<T>(string value)
{
    // or ConvertFromInvariantString if you are doing serialization
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(value);
}

我必须像这样称呼它

Parse<Int32>(Some string value);
Parse<DateTime>(Some string value);

我正在尝试 that instead of giving the result type explicitly ,我可以像

一样
Parse<Type.GetType("Int32")>(Some string value);

2 个答案:

答案 0 :(得分:5)

泛型不在这里。主要问题是您尝试围绕类型标识采用快捷方式。类型的名称​​不只是您在程序中使用的类型名称。它还包括声明它的名称空间,存储它的程序集的显示名称,程序集的版本号以及程序集强名称的公钥标记。换句话说,Type.AssemblyQualifiedName。

这要求您编写与此类似的代码:

 Parse(Type.GetType("System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089""), SomeStringValue);

那会很好用。但我猜你不会喜欢写这个。否则,可以让您深入了解编译器在读取&#34; Int32&#34;在你的程序中。它将在其符号表中查找已添加的引用程序集,并注意该表中可能存在的匹配项,考虑 using 指令的有效性。

您必须在程序中实现类似的功能。编译器符号表的等价物是Dictionary<string, Type>。您可以通过使用您希望使用短字符串名称的类型填充它来填充它。喜欢

  LookupTable.Add("Int32", typeof(int));
  LookupTable.Add("String", typeof(string));
  // etc...

现在你可以写:

  Parse(LookupTable["Int32"], SomeStringValue);

那会很好用。但我猜你不会喜欢写这个。很难击败编译器。

答案 1 :(得分:2)

我认为如果你需要在运行时而不是编译时指定类型(如在你将“Int32”指定为字符串的示例中),那么首先需要用以下内容重写代码:

public static object Parse(Type destinationType, string value)
{
    return TypeDescriptor.GetConverter(destinationType).ConvertFromString(value);
}

现在你可以调用这个新方法写作:

var myValue = Parse(Type.GetType("System.Int32"), "33243");

Type.GetType要求您指定完整的命名空间和程序集名称(程序集限定名称),但对于mscorlib类型(如所有基本类型)或当前正在执行的程序集类型,您只需指定完整的命名空间,例如System.Int32System.DateTime。请参阅MSDN

还要考虑还有其他选项可以将原始类型转换为字符串或从字符串转换。我建议你使用Convert.ChangeType。此方法基本上检查指定的类型是否支持IConvertible接口。基本上你可以写:

var myValue = Convert.ChangeType("23423", typeof(Int32));
or
var myValue = Convert.ChangeType("23423", Type.GetType("System.Int32"));

它还支持InvariantCulture:

var myValue = Convert.ChangeType("23423", typeof(Int32), CultureInfo.InvariantCulture);

还有一个很好的库,它结合了IConvertible功能和TypeConverter,请参阅Code Project: Universal Type Converter。这个库有许多有用的功能,它是免费的,也可以在nuget上使用。