有什么最快的方法来检查一个字符串是否可以被解析?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (51)

我将CSV文件解析为具有强类型属性的对象列表。这涉及从文件中的每个字符串值解析到一个IConvertible类型(intdecimaldoubleDateTime使用等)。

我使用a try catch来处理解析失败时的情况。然后记录下发生该异常的具体细节,以便进一步调查。下面是实际的解析代码:

try
{
    parsedValue = TypeDescriptor.GetConverter(type).ConvertFromString(dataValue);
}
catch (Exception ex)
{
    // Log failure
}

问题:

值成功解析后,该过程很快。当分析数据有很多无效的数据时,这个过程可能会花费数千次(由于捕获异常)。

慢了4500倍。

提问于
用户回答回答于

如果你有一组已知类型的转换,则可以执行一系列if/elseif/elseif/else(或switch/case在类型名称上)实质上将其分配给专门的解析方法。这应该是相当快的。

如果你仍然有性能问题,你也可以创建一个查找表,这将允许你添加新的解析方法:

给定一些基本的解析包装:

public delegate bool TryParseMethod<T>(string input, out T value);

public interface ITryParser
{
    bool TryParse(string input, out object value);
}

public class TryParser<T> : ITryParser
{
    private TryParseMethod<T> ParsingMethod;

    public TryParser(TryParseMethod<T> parsingMethod)
    {
        this.ParsingMethod = parsingMethod;
    }

    public bool TryParse(string input, out object value)
    {
        T parsedOutput;
        bool success = ParsingMethod(input, out parsedOutput);
        value = parsedOutput;
        return success;
    }
}

然后,可以设置一个conversion helper,它执行查找并调用适当的解析器:

public static class DataConversion
{
    private static Dictionary<Type, ITryParser> Parsers;

    static DataConversion()
    {
        Parsers = new Dictionary<Type, ITryParser>();
        AddParser<DateTime>(DateTime.TryParse);
        AddParser<int>(Int32.TryParse);
        AddParser<double>(Double.TryParse);
        AddParser<decimal>(Decimal.TryParse);
        AddParser<string>((string input, out string value) => {value = input; return true;});
    }

    public static void AddParser<T>(TryParseMethod<T> parseMethod)
    {
        Parsers.Add(typeof(T), new TryParser<T>(parseMethod));
    }

    public static bool Convert<T>(string input, out T value)
    {
        object parseResult;
        bool success = Convert(typeof(T), input, out parseResult);
        if (success)
            value = (T)parseResult;
        else
            value = default(T);
        return success;
    }

    public static bool Convert(Type type, string input, out object value)
    {
        ITryParser parser;
        if (Parsers.TryGetValue(type, out parser))
            return parser.TryParse(input, out value);
        else
            throw new NotSupportedException(String.Format("The specified type \"{0}\" is not supported.", type.FullName));
    }
}

然后用法可能是这样的:

//for a known type at compile time
int value;
if (!DataConversion.Convert<int>("3", out value))
{
    //log failure
}

//or for unknown type at compile time:
object value;
if (!DataConversion.Convert(myType, dataValue, out value))
{
    //log failure
}
用户回答回答于

如果你知道要解析的类型,请使用TryParse方法:

String value;
Int32 parsedValue;
if (Int32.TryParse(value, parsedValue) == True)
    // actions if parsed ok
else
    // actions if not parsed

其他类型相同

Decimal.TryParse(value, parsedValue)
Double.TryParse(value, parsedValue)
DateTime.TryParse(value, parsedValue)

或者可以使用这个解决方法:

为每个相同名称但签名不同的类型创建一个解析方法(将TryParse包装在其中):

Private bool TryParsing(String value, out Int32 parsedValue)
{
    Return Int32.TryParse(value, parsedValue)
}

Private bool TryParsing(String value, out Double parsedValue)
{
    Return Double.TryParse(value, parsedValue)
}

Private bool TryParsing(String value, out Decimal parsedValue)
{
    Return Decimal.TryParse(value, parsedValue)
}

Private bool TryParsing(String value, out DateTime parsedValue)
{
    Return DateTime.TryParse(value, parsedValue)
}

然后你可以使用方法TryParsing你的类型

所属标签

可能回答问题的人

  • HKC

    红客学院 · 创始人 (已认证)

    26 粉丝7 提问5 回答
  • Dingda

    Dingda · 站长 (已认证)

    4 粉丝0 提问3 回答
  • 西风

    renzha.net · 站长 (已认证)

    9 粉丝1 提问3 回答
  • 螃蟹居

    1 粉丝0 提问2 回答

扫码关注云+社区

领取腾讯云代金券