2016-01-13 65 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; 
     } 
    } 
}