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

本文关键字:类型 是否 String 转换 检查 | 更新日期: 2023-09-27 18:14:24

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

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

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

解决方案1: Convert.ChangeType() with 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 if/else链与类型检查和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检查会拖累性能(我不一定要在这一点上进行优化,我只是想确保我考虑了其他选项)。

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

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

在最近被问到的另一个问题上,我找到了一个比我最初的想法更好的解决方案。

parapura rajkumar使用TypeConverter类的思路是正确的,但是CanConvertFrom方法对非异常事件所需的异常处理是我试图避免的。

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

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

考虑使用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");
        }
    }

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