2016-01-13 64 views
1

我有以下代码并需要添加try-catch-block,因为例如:如果提供的字符串错误,转换为整数可能无法正常工作。问题只出现在极少数情况下,但我当然希望避免崩溃。将Try-Catch块添加到XAML代码

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(); 
    }); 
} 

我试过的try-catch在几个地方,但我没有找到一个正确:-(我应该在哪里增加吗?万一“项目ID”不整我想跳过这个。?!项目和过程中的所有其他的将这项工作 非常感谢

回答

2

简短的回答是,你不能在你描述的方式使用一个try/catch

你有两个选择:

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

的第二种方法是进行提取int转换成做的尝试/捕获和例如,返回一个元组指示成功和值的单独的方法,虽然这可通过使用Option<int>类型被大大简化,如由我自己的Succinc<T> library提供。它支持提供一个值或无:

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(); 
    }); 
} 
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; 
2

如果你只是担心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(); 
+1

为什么向下票? –

+0

不知道是谁否决。我喜欢这个主意,谢谢! – K232

+0

如果我的回答帮助解决了您的问题,请将其标记为已接受的答案。 –

1

您可以使用,可以转换一个静态方法字符串/对象/ 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(); 
    }); 
} 

你可以捆绑与例外HANDELING转换方法,如下面的

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; 
     } 
    } 
}