C# 如何验证字符串是否可以转换为特定类型?

C# 如何验证字符串是否可以转换为特定类型?,c#,parsing,types,C#,Parsing,Types,我有可能是int,datetime,boolean,byte等的字符串 如何验证字符串是否可以在不使用每种类型的TryParse的情况下转换为这些类型?除了在try-catch块中调用Parse是一个糟糕的想法外,我认为唯一的替代方法是编写自己的解析算法也是一个糟糕的想法 你为什么不想使用TryParse方法 您可以使用正则表达式来确定它们的类型。虽然如果需要在int和byte之间进行区分(如果值小于255),这会有点麻烦 public class GenericsManager { p

我有可能是int,datetime,boolean,byte等的字符串


如何验证字符串是否可以在不使用每种类型的TryParse的情况下转换为这些类型?

除了在try-catch块中调用Parse是一个糟糕的想法外,我认为唯一的替代方法是编写自己的解析算法也是一个糟糕的想法


你为什么不想使用TryParse方法

您可以使用正则表达式来确定它们的类型。虽然如果需要在int和byte之间进行区分(如果值小于255),这会有点麻烦

public class GenericsManager
{
    public static T ChangeType<T>(object data)
    {
        T value = default(T);

        if (typeof(T).IsGenericType &&
          typeof(T).GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            value = (T)Convert.ChangeType(data, Nullable.GetUnderlyingType(typeof(T)));

        }
        else
        {
            if (data != null)
            {
                value = (T)Convert.ChangeType(data, typeof(T));
            }
        }

        return value;
    }
}
在这里不是很有用,但我想您可以使用它,并验证结果是否不等于该类型的默认值

但是,tryparse要好得多,并且达到了您想要做的程度。

您可以混合使用tryparse和正则表达式。这不是一个漂亮的代码,但是速度很快,并且您可以在任何地方使用该方法

有一个关于布尔类型的问题。0或1可以表示布尔值,但也可以是Byte类型。我分析了正确和错误的文本值,但是关于您的业务规则,您应该决定什么最适合您

public static Type getTypeFromString(String s)
        {
            if (s.Length == 1)
                if (new Regex(@"[^0-9]").IsMatch(s)) return Type.GetType("System.Char");
            else
                return Type.GetType("System.Byte", true, true);

            if (new Regex(@"^(\+|-)?\d+$").IsMatch(s))
            {
                Decimal d;
                if (Decimal.TryParse(s, out d))
                {
                    if (d <= Byte.MaxValue && d >= Byte.MinValue) return Type.GetType("System.Byte", true, true);
                    if (d <= UInt16.MaxValue && d >= UInt16.MinValue) return Type.GetType("System.UInt16", true, true);
                    if (d <= UInt32.MaxValue && d >= UInt32.MinValue) return Type.GetType("System.UInt32", true, true);
                    if (d <= UInt64.MaxValue && d >= UInt64.MinValue) return Type.GetType("System.UInt64", true, true);
                    if (d <= Decimal.MaxValue && d >= Decimal.MinValue) return Type.GetType("System.Decimal", true, true);
                }
            }

            if (new Regex(@"^(\+|-)?\d+[" + NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator + @"]\d*$").IsMatch(s))
            {
                Double d;
                if (Double.TryParse(s, out d))
                {
                    if (d <= Single.MaxValue && d >= Single.MinValue) return Type.GetType("System.Single", true, true);
                    if (d <= Double.MaxValue && d >= Double.MinValue) return Type.GetType("System.Double", true, true);
                }
            }

            if(s.Equals("true",StringComparison.InvariantCultureIgnoreCase) || s.Equals("false",StringComparison.InvariantCultureIgnoreCase))
                return Type.GetType("System.Boolean", true, true);

            DateTime dateTime;
            if(DateTime.TryParse(s, out dateTime))
                return Type.GetType("System.DateTime", true, true); 

            return Type.GetType("System.String", true, true); 
        }

你不想使用TryParse有什么特别的原因吗?这是最简单、最健壮的方法,可能也是最快的方法之一。因为我有很多可能的类型,所以使用解析/tryparsing需要编写很多代码,所以在使用这种丑陋的方法之前,我正在寻找更好的方法。我想你会遇到很多if/else语句。我不认为有什么更干净的方法可以做到这一点。这正是我一直在寻找的解决方案类型。无论如何,我已经实现了类似的解决方案,它更适合我的使用:private bool是typeofstring value,其中T:struct{if string.IsNullOrEmptyvalue{throw new ArgumentExceptiontext不能为null或空,value;}bool是fromtype=false;Type Type=typeofT;MethodInfo tryParse=Type.GetMethodTryParse,new Type[]{typeofstring,type.MakeByRefType};如果tryParse!=null{isFromType=booltryParse.Invokenull,new[]{value,null};}返回isFromType;}谢谢!你正在为此使用反射?我不太确定你想用它做什么,但是反射是一个非常昂贵的过程,它只需要节省几行代码。我几乎更喜欢用try/catch invalidcasteption块之类的东西包装ChangeTypeobject数据方法-我想这是我头脑中正确的异常,并且从那里的try/catch流返回bool。-完全意识到这两件事都不是一件好事。