2011-11-14 27 views
9

我必须验证用户输入数据并确保字符串值可以转换为运行时指定的类型。我不一定需要做实际的转换,只是测试以确保输入值是有效的。我没有找到一个内置的类或方法来执行这种评估,但如果我错过了一个,请告诉我。如果有任何特定于版本的解决方案,我正在使用C#4.0。检查字符串是否可以转换为C#中的给定类型

该方法只需处理“标准”类型(内置值数据类型和字符串)。我需要评估的唯一自定义类型是在库中定义的特定枚举类型。

我有2个解决方案我目前正在称重,但都不是完美的,所以我希望有第三种选择(或者我错过了框架内置的东西)。我非常倾向于解决方案2,因为在解决方案1中使用try-catch似乎是错误的。

解决方案1 ​​Convert.ChangeType()用的try/catch

public Boolean CheckType(String value, Type type) 
{ 
    try 
    { 
     var obj = Convert.ChangeType(value, type); 
     return true; 
    } 
    catch(InvalidCastException) 
    { 
     return false; 
    } 
    catch(FormatException) 
    { 
     return false; 
    } 
    catch(OverflowException) 
    { 
     return false; 
    } 
    catch(ArgumentNullException) 
    { 
     return false; 
    } 
} 

解决方案2如果使用类型检查/别的链的TryParse

public Boolean CheckType(String value, Type type) 
{ 
    if (type == typeof(String)) 
    { 
     return true; 
    } 
    else if (type == typeof(Boolean)) 
    { 
     Boolean b; 
     return Boolean.TryParse(value, out b); 
    } 
    else if (type == typeof(Int32)) 
    { 
     Int32 i; 
     return Int32.TryParse(value, out i); 
    } 
    else if (type == typeof(Int64)) 
    { 
     Int64 l; 
     return Int64.TryParse(value, out l); 
    } 
    // similar code to check all other types 
    // (Int16, UInt32, UInt64, UInt16, Byte, SByte, Single, Double, Decimal, 
    // Enum, Char, DateTime) 
    . 
    . 
    . 
    . 
    . 
    else 
     throw new ArgumentException("Invalid type evaluation"); 

} 

这种方法可称为几百甚至如果输入数据严重混乱或损坏,则在短时间间隔内重复上千次,所以我担心重复的if/else检查会对性能造成拖累(我现在不一定要优化,我只是想确保我正在考虑其他选项)。

我对这两种解决方案的另一个问题是,两者实际上都将字符串值转换为预期类型的​​新值,并且在这两种情况下,我都在吞咽结果。

+0

@JeremyMcGee我看到了你链接的问题,但由于我并不想转换值,只是测试它可以转换,我不认为我的问题必然是重复的。 – psubsee2003

+0

@ psubsee2003:检查某些东西是否可以转换并实际转换它的工作量通常很小。 – Joe

+0

@Joe我有这样的感觉,但由于TryParse方法是如此之快,没有明显的例外,我想知道是否有内置的方式来检查转换之前。 – psubsee2003

回答

3

我宁愿TryParse三通,因为异常是昂贵的(表现)。

+0

最后,由于TypeConverter答案需要异常处理避免。 – psubsee2003

14

考虑使用TypeConverter和通用方法。这避免了大量if语句。请添加你自己的错误处理根据MSDN文档

class Program 
    { 
     static T convert<T>(string s) 
     { 
      var typeConverter = TypeDescriptor.GetConverter(typeof(T)); 
      if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string))) 
      { 
       return (T) typeConverter.ConvertFrom(s); 
      } 

      return default(T); 
     } 

     static void Main(string[] args) 
     { 
      int x = convert<int>("45"); 
     } 
    } 
+0

我不确定我遵循如何解决检查类型的原始问题是否有效。如果我将一个无效值传递给转换器(例如,对于int为“14.1”),则会引发FormatException。我的第一个解决方案已经做到了,所以我不确定为什么这是更可取的。 – psubsee2003

+2

这是可取的,因为该方法是通用的,并且不需要新的**如果块**对于添加的每个新类型 –

11

我发现了一个比我最初提出的另一个question最初的想法更好的解决方案。

parapura rajkumar在TypeConverter类的正确轨道上,但对于非例外事件CanConvertFrom方法所需的异常处理是我试图避免的。

TypeConverter.IsValid方法解决了我的问题,虽然它不是理想的,因为IsValid方法只是CanConvertFrom方法的包装和所需的异常处理。

private Boolean CanCovert(String value, Type type) 
{ 
    TypeConverter converter = TypeDescriptor.GetConverter(type); 
    return converter.IsValid(value); 
} 
相关问题