【问题标题】:Test if string can be converted to other, various type测试字符串是否可以转换为其他各种类型
【发布时间】:2011-11-22 12:59:59
【问题描述】:

(已解决)我正在构建一个应用程序,该应用程序可以根据 XML 文件中的一些描述动态创建其某些控件。
我现在需要的是与 TryParse() 方法非常相似的东西:检查(不抛出/捕获异常)的可能性,是否可以将字符串变量中的文本转换(或解析)为我在其他变量中具有的名称(myType)。
问题是myType 可以是任何.NET 类型:DateTime, Bool, Double, Int32 等。

例子:

string testStringOk = "123";
string testStringWrong = "hello";
string myType = "System.Int32";

bool test1 = CanCovertTo(testStringOk, myType);      //true
bool test2 = CanCovertTo(testStringWrong, myType);   //false

CanCovertTo(string testString, string testType) 函数应该是什么样子的?

我得到的最接近的是以下代码:

private bool CanCovertTo(string testString, string testType)
{
    Type type = Type.GetType(testType, null, null);
    TypeConverter converter = TypeDescriptor.GetConverter(type);

    converter.ConvertFrom(testString);  //throws exception when wrong type
    return true;
}

但是,它在尝试从错误的字符串转换时会引发异常,我不想为此使用try {} catch()


解决方案:

private bool CanCovertTo(string testString, string testType)
{
    Type type = Type.GetType(testType, null, null);
    TypeConverter converter = TypeDescriptor.GetConverter(type);
    return converter.IsValid(testString);
}

【问题讨论】:

  • 你为什么不喜欢使用 try/catch 呢?
  • 您为什么要在名为 CanConvert 的函数中转换值?你不能只做“return converter.CanConvertFrom(typeof(string))”
  • @PVitt:这只是关于“最佳实践”,我读过您应该避免使用正常程序操作处理异常。我相信这就是为什么 TryParse() 方法与 Parse() 一起存在的原因。老实说,如果有比这更好的方法,可以让我做我需要的,我更喜欢那个。 :)
  • @Grrbrr404:你说得对,CanConvertFrom(typeof(string)) 在该代码中不是必需的。我已经修改了帖子。
  • 类似于我之前提出的一个问题:stackoverflow.com/q/8122604/250725

标签: c# visual-studio-2010 .net-4.0


【解决方案1】:

我会检查方法TypeConverter.IsValid,虽然:

从 .NET Framework 版本 4 开始,IsValid 方法从 CanConvertFrom 和 ConvertFrom 方法捕获异常。如果输入值类型导致 CanConvertFrom 返回 false,或者如果输入值导致 ConvertFrom 引发异常,则 IsValid 方法返回 false。

这意味着如果你自己不使用 try...catch 你将转换两倍的值。

【讨论】:

  • 很好的答案。这实际上解决了我上周提出的一个问题。
【解决方案2】:

您应该使用泛型,而不是将类型作为字符串传递,例如

public bool CanConvert<T>(string data)
{
    TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
    return converter.IsValid(data);
}

用法

bool test1 = CanConvert<Int32>("1234"); // true
bool test2 = CanConvert<Int32>("hello"); // false

【讨论】:

  • 泛型要求 OP 知道编译类型时的类型,而他似乎不知道。
  • 会很完美,如果我以前知道确切的类型,或者可以这样做:bool test1 = CanConvert &lt;Type.GetType(myType, null, null)&gt; (testStringOk); 但是我不知道类型,它是动态读取的,并且保留在字符串变量中。
  • @James:你能使用Type 对象作为通用类型参数吗?我不认为这是可能的。
  • @psubsee2003 - 可以使用反射来完成,但是,我发布的内容完全错误!删除了,我用泛型已经有一段时间了,所以有点生疏了!
【解决方案3】:

如果它们只是内置的 .NET 类型,您可以基于 System.TypeCode 进行转换。您可以将类型代码存储在您的 XML 中(或将您的类型字符串转换为类型代码)并执行以下操作:

switch (code)
{
    case TypeCode.Boolean:
        bool.TryParse(value, out result);
        break;
    case TypeCode.Int32:
        int.TryParse(value, out result);
    ...
}

【讨论】:

  • 我一直在考虑,但是行数太多了。 :) 使用 TypeConverter.IsValid,它可以用 3 行来完成。无论如何谢谢:)
猜你喜欢
  • 2012-08-16
  • 1970-01-01
  • 2010-12-01
  • 1970-01-01
  • 2017-07-02
  • 1970-01-01
  • 2011-12-29
  • 2013-03-16
  • 2019-06-14
相关资源
最近更新 更多