【问题标题】:Generic function for parsing objects解析对象的通用函数
【发布时间】:2013-03-05 11:10:44
【问题描述】:

将字符串解析为从参数中获取的类型的最佳方法是什么?

我目前正在使用以下函数解析 XML 节点,但希望使其具有通用性。

    private void ParseSettings(XmlDocument doc)
    {
        IsFormVisible = (bool) ParseNode(doc, "Settings/IsFormVisible", IsFormVisible);
        UpdaterRunInterval = (int) ParseNode(doc, "Settings/UpdaterRunInterval", UpdaterRunInterval);
        UpdaterLastRunTime = (DateTime) ParseNode(doc, "Settings/UpdaterLastRunTime", UpdaterLastRunTime);
    }

    private object ParseNode(XmlDocument doc, string node, object defaultValue)
    {
        try
        {
            XmlNode xmlNode = doc.SelectSingleNode(node);
            if (xmlNode == null)
                return defaultValue;
            string text = xmlNode.InnerText;
            if (defaultValue is int)
                return int.Parse(text);
            if (defaultValue is bool)
                return bool.Parse(text);
            if (defaultValue is string)
                return text;
            if (defaultValue is DateTime)
                return DateTime.Parse(text);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return defaultValue;
    }

【问题讨论】:

  • 如果您认为一般情况下无法做到这一点。我认为您最好使用 int.TryPares、bool.TryParse 等,然后在它们不解析时返回适当的错误消息。
  • 我故意返回默认值以重新创建损坏或丢失的节点。我只是不喜欢必须检查类型并为每个类型调用 Parse。
  • @MiroslavPopov - 看看答案!
  • 您仍然需要检查类型,即使您将方法设为通用。没有 where 子句可以应用于泛型方法,您可以在其中执行 T.TryParse 之类的操作,因为没有包含所有这些类型共享的 Parse 或 TryParse 的基类。

标签: c# xml parsing generics


【解决方案1】:
private T ParseNode<T>(XmlDocument doc, string node, T defaultValue)
{
    try
    {
        XmlNode xmlNode = doc.SelectSingleNode(node);
        if (xmlNode == null)
            return defaultValue;
        string text = xmlNode.InnerText;
        return SafeConvert(text, defaultValue);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    return defaultValue;
}

public static T SafeConvert<T>(string s, T defaultValue)
{
    if ( string.IsNullOrEmpty(s) )
        return defaultValue;
    return (T)Convert.ChangeType(s, typeof(T));
}

【讨论】:

    【解决方案2】:

    试试类似的东西:

    private static T ParseNode<T>(XmlDocument doc, string node, object defaultValue)
    {
        object ret = defaultValue;
        try
        {
    
            XmlNode xmlNode = doc.SelectSingleNode(node);
            if (xmlNode == null)
                return default(T);
            string text = xmlNode.InnerText;
            if (defaultValue is int)
                ret = int.Parse(text);
            if (defaultValue is bool)
                ret =  bool.Parse(text);
            if (defaultValue is string)
                ret = text;
            if (defaultValue is DateTime)
                ret = DateTime.Parse(text);
    
            return (T) ret;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        return (T)ret;
    }
    

    我不能保证,这是完美的做法,但它确实有效!

        IsFormVisible = ParseNode<bool>(doc, "Settings/IsFormVisible", true);
        UpdaterRunInterval = ParseNode<int>(doc, "Settings/UpdaterRunInterval", 1);
        UpdaterLastRunTime = ParseNode<DateTime>(doc, "Settings/UpdaterLastRunTime", 1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 1970-01-01
      • 2021-03-17
      • 2023-03-31
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多