Как проверить строку можно преобразовать в определенный тип? - PullRequest
0 голосов
/ 24 июня 2009

У меня есть строка, которая может быть int, datetime, boolean, byte и т. Д. '

Как я могу проверить, что строка может быть преобразована в эти типы без использования TryParse каждого типа?

Ответы [ 4 ]

3 голосов
/ 24 июня 2009
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 намного лучше, и в смысле того, что вы пытаетесь сделать.

3 голосов
/ 24 июня 2009

Помимо вызова Parse () внутри блока try catch (ужасная идея), я думаю, что единственная альтернатива - написать собственный алгоритм синтаксического анализа (также плохая идея).

Почему вы не хотите использовать методы TryParse?

1 голос
/ 24 июня 2009

Вы можете использовать регулярные выражения, чтобы определить, какого типа они могут быть. Хотя будет немного сложнее, если вам нужно различать int и байт, если значение меньше 255.

0 голосов
/ 24 июня 2009

Вы можете использовать смесь между TryParse и регулярными выражениями. Это не красивый код, но быстрый, и вы можете использовать метод везде.

Проблема с типом Boolean . 0 или 1 могут представлять логические значения, но также могут иметь тип Byte . Я проанализировал текстовые значения true и false , но в отношении ваших бизнес-правил вы должны решить, что лучше для вас.

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); 
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...