检查String是否可以在C#中转换为给定类型

psu*_*003 9 c# type-conversion

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

该方法只需要处理"标准"类型(内置值数据类型加上String).我需要评估的唯一自定义类型是库中定义的特定枚举类型.

我有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;
    }
}
Run Code Online (Sandbox Code Playgroud)

解决方案2 if/else链接Type Check和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");

}
Run Code Online (Sandbox Code Playgroud)

如果输入数据严重搞乱或损坏,这种方法可能在短时间内被调用几百甚至一千次,所以我担心重复的if/else检查会拖累性能(我不是在这一点上我一定想要优化,我只是想确保我正在考虑其他选择).

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

par*_*mar 15

考虑使用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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 这是首选,因为该方法是通用的,并且对于您添加的每个新类型,不需要新的**if块** (2认同)

psu*_*003 15

在最近提出的另一个问题中,我找到了比我最初的想法更好的解决方案.

parapura rajkumar使用TypeConverter类在正确的轨道上,但是CanConvertFrom非特殊事件的方法所需的异常处理是我试图避免的.

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

private Boolean CanCovert(String value, Type type)
{
    TypeConverter converter = TypeDescriptor.GetConverter(type);
    return converter.IsValid(value);
}
Run Code Online (Sandbox Code Playgroud)


Fis*_*aen 5

我更喜欢这种TryParse方式,因为异常是昂贵的(性能)。