将Try-Catch块添加到XAML代码中

本文关键字:XAML 代码 添加 Try-Catch | 更新日期: 2023-09-27 18:30:14

我有以下代码,需要添加一个try-catch块,因为例如,如果提供的字符串错误,则转换为integer可能无法正常工作。问题只出现在极少数情况下,但我当然想避免崩溃。

private async Task<List<MyItem>> ParseFeed(string text)
{
    XNamespace ns = "http://mynamespace/";
    return await Task.Run(() =>
    {
        var xdoc = XDocument.Parse(text);
        return (from XElement item in xdoc.Descendants("item")
                select new MyItem
                {
                    Subject = (string)item.Element(ns + "Subject"),
                    CreationDate = (System.DateTime)System.DateTime.Parse((string)item.Element(ns + "CreationDate")),
                    ItemID = (int)item.Element(ns + "ItemID")
                }).ToList();
    });
}

我试过在几个地方尝试catch,但没有找到正确的:-(我应该把它添加到哪里?如果"ItemID"不是Integer,我想跳过这个项目,处理所有其他项目。这行吗?非常感谢!

将Try-Catch块添加到XAML代码中

简单的答案是,您不能以所描述的方式使用try/catch。

你有两个选择:

首先,您可以放弃LINQ,使用标准的foreachlist.Add(),并使用try/catch。

第二种方法是将int转换提取到一个单独的方法中,该方法执行try/catch,例如,返回一个指示成功和值的元组,尽管这可以通过使用Option<int>类型来大大简化,例如由我自己的Succinc<T>图书馆它支持提供有值或无值:

private async Task<List<MyItem>> ParseFeed(string text)
{
    XNamespace ns = "http://mynamespace/";
    return await Task.Run(() =>
    {
        var xdoc = XDocument.Parse(text);
        return (from XElement item in xdoc.Descendants("item")
                let possibleItemID = item.Element(ns + "ItemID").ParseInt()
                where possibleItemID.HasValue
                select new MyItem
                {
                    Subject = (string)item.Element(ns + "Subject"),
                    CreationDate = (System.DateTime)System.DateTime.Parse((string)item.Element(ns + "CreationDate")),
                    ItemID = possibleItemID.Value
                }).ToList();
    });
}

如果您只是担心ItemID不是整数,那么添加一个where子句:

int itemId;
return (from XElement item in xdoc.Descendants("item")
        where int.TryParse(item.Element(ns + "ItemID"), out itemId)
        select new MyItem
        {
            Subject = (string)item.Element(ns + "Subject"),
            CreationDate = (System.DateTime)System.DateTime.Parse((string)item.Element(ns + "CreationDate")),
            ItemID = itemId
        }).ToList();

您可以使用一个静态方法,该方法可以将string/object/T转换为Int32,并处理转换过程中引发的任何异常。请注意,您不能对LINQ to Entities/Xml使用这类方法,相反,您需要在第一次选择后调用.ToList(),这将是您的原始数据,而不是.select(…将使用所需转换方法的原始数据。以下是代码示例。

private async Task<List<MyItem>> ParseFeed(string text)
{

    XNamespace ns = "http://mynamespace/";
    return await Task.Run(() =>
    {
        var xdoc = XDocument.Parse(text);
        return (from XElement item in xdoc.Descendants("item")
                select new
                {
                    Subject = (string)item.Element(ns + "Subject"),
                    CreationDate =    (System.DateTime)System.DateTime.Parse((string)item.Element(ns + "CreationDate")),
                    ItemID = ns 
                }).ToList()
                    .select(x=> new MyItem{
                        x.Subject,
                        x.CreationDate, 
                        ItemID  = SafeConvert.ToInt32(ns)
                    }).ToList();
    });
}

您可以将转换方法与异常处理捆绑在一起,如以下

public static class SafeConvert
{
    public static int ToInt32(object number)
    {
        try
        {
            // if (TypeValidator.IsInt(number)) // If you want to check type before cast to avoid any potential exceptions
            return Convert.ToInt32(number);
        }
        catch
        { // Log you exception}
            return 0;
        }
    }
}

就我个人而言,我只是从Linq切换到常规的foreach循环,并使用TryParse方法

var xdoc = XDocument.Parse(text);
var list = new List<MyItem>();
foreach(var item in xdoc.Descendants("item"))
{
    DateTime creationDate;
    int itemId;
    if(int.TryParse((string)item.Element(ns + "ItemID"),out itemId)
       && DateTime.TryParse((string)item.Element(ns + "CreationDate"), out creationDate))
    {
        list.Add(new MyItem
            {
                Subject = (string)item.Element(ns + "Subject"),
                CreationDate = creationDate,
                ItemID = itemId
            });
    }
}
return list;