2012-03-15 95 views
4

我有一些代码这样为什么try块需要一个catch

try 
{ 
    result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; 
} catch { } 

现在,我不知道在调用此呼吁,如果我要寻找的属性存在(好醇的SharePoint之前)。

因此,我可以编写我想要创建的代码的唯一线性方式就是这样。

try 
{ 
    result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; 
} catch { } 
try 
{ 
    result.LastName = nodes[myIdx].Attributes["ows_LastName"].Value; 
} catch { } 

.... 

现在我没有使用这段代码的catch部分,并最终导致大量完全冗余的行。

为什么我不能只是做

try { result.FirstName = nodes[myIdx].Attributes["ows_FirstName"].Value; } 

那么,为什么我们明确被迫宣布,即使没有被处理的catch块?我确信有一个很好的理由,但不能解决它。

编辑:在大家开始关注吞咽异常是不好的,等等等等。我们(和我)都知道这些论点,但在这个(和许多)现实世界的场景中,没有什么例外,我无法做(或需要做)来解决这个问题。

+1

阅读[文章] [1] [1]:http://stackoverflow.com/questions/1573130/net-throwing-custom-exceptions – CheGueVerra 2012-03-15 02:20:47

+0

@CheGueVerra - 不知道如何自己相关的我的问题? – 2012-03-15 02:22:03

回答

5

的他们是不是多余的 - 他们有一个特定的目的。默认情况下,缺少catch块会将异常重新抛出到调用方法。一个空的catch块实质上“吞食”了异常并让程序继续,忽略了是否引发了异常;通常是一种不好的做法

根本就没有任何特别之处异常

它可能是真实的一个类型的异常的可能不是“例外”在这种情况下,但是这不是异常可能发生。您应该处理该例外并适当处理任何其他问题。

例如 -

如果nodes为空?如果myIdx超出nodes阵列的范围,该怎么办?这两个条件中的任何一个都是例外,您应该专门处理它们或让调用程序处理它们并采取适当的行动。

[有]什么我可以做(或需要做的)来修复行为

你可能不能够修复,但你可能需要的知道它。在这种情况下,程序的行为有什么不同?记录消息?发出警告?设置默认值?什么都不做可能是一个合适的答案,但很有可能不是对任何可能的异常的适当回应。

+0

现在这是我见过的第一个合理的答案。我没有考虑如果发生另一种类型的例外情况,我会吞咽的情况(虽然在我的例子中并没有真正相关,但肯定会采用)。感谢您的意见。 – 2012-03-15 02:36:33

6

如果你想吞下异常(catch它但什么都不做),你必须明确地这样做。

这通常是不好的做法,所以没有理由提供一个语法快捷方式。您通常应该:

  1. 以某种方式处理异常。这可能意味着:
 
a. Retry 
b. Rethrow it (preserving the inner exception) with a more meaningful message. 
c. Do it another way. 
d. Log it (though logging and rethrowing might be better). 
e. Other 

2.  就让它泡了(没有尝试,或只是尝试/最后)。

1

try/catch块的设计显式用于捕获和处理抛出应用程序中的异常。

简单地吞下异常通常是一个坏主意(即使您只是记录异常),并且必须明确地完成。

2

推理可能是因为你不应该捕捉异常,如果你不能处理它。如果没有相应的catch,允许您登录try将无能为力,只会导致最糟糕的做法。

至于您所引用的特定代码,难道您不能在尝试访问索引器之前进行空检查吗?

+0

请参阅我对Simon Wang和Xander的回复我的具体代码 – 2012-03-15 02:32:41

1

它是语言语法的一部分。如果没有至少一个catchfinally,您不能try。没有独立的try,只有try-catchtry-finallytry-catch-finally

它根本没有任何意义try一些代码,如果你不打算理会处理异常(catch),或至少确保一些后续代码始终运行,无论发生了什么(这是finally)。

+0

想必他是问为什么这是语法。 – 2012-03-15 02:24:21

4

为什么不只是检查项目是不是null

if(nodes[myIdx].Attributes != null && 
    nodes[myIdx].Attributes["ows_FirstName"] != null) { 
    /* ... your code ... */ 
} 

或者:

if(nodes[myIdx].Attributes != null) { 
    if(nodes[myIdx].Attributes["ows_FirstName"] != null) { 
     /* ... your code ... */ 
    } 
    if(nodes[myIdx].Attributes["ows_LastName"] != null) { 
     /* ... your code ... */ 
    } 
} 
+0

由于sharepoint XML webservices具有简单地忽略空值而非提供空值的特性的奇妙行为。 – 2012-03-15 02:29:27

+0

@MaximGershkovich我的更新答案是否可用? – xandercoded 2012-03-15 02:32:21

+1

这是一个很好的解决方案。 – tsells 2012-03-15 02:39:38

1

这几乎已经在这个问题回答说:C#: should all exceptions be caught

基本上,如果你正在追赶它,那么你应该用它做什么,否则不要抓它。在你的情况下,为什么你不能检查属性值是否先存在?

2

必须有另一种方式来检查,如果存在的属性或没有,你不应该使用异常处理一些功能性的目的,你这样的代码:

try 
{ 
    newstring = oldString.ToString(); 
} 
catch{} 

你应该做的是:

if(oldString != null) 
{ 
    newstring = oldString; 
} 

请记住,try catch是用于处理名为'exception'的东西

+0

Sharepoint XML webservices简单地省略了空值而不是空值的属性。这意味着对于每一个数据子集(IE:每行),我都需要运行数据并检查。在我看来,简单地允许例外发生(虽然有争议)更实际。 – 2012-03-15 02:31:25

0

您不应该有空的catch块。这是糟糕的编程习惯。

让我想起了经典的ASP On Error Resume Next

1

看起来您正在使用SharePoint Web Services之一,所以返回类型是某种XmlElement?我很确定有一种方法来检查是否存在一个属性,这比抛出异常更便宜。

另外,你需要一个帮助器方法来封装检查和数据检索。

+0

我不相信有一种方法来检查XmlAttributeCollection(我看过,但可能是错误的),但即使有我仍然会争辩说,有这种情况下,这种语法将是适当的。 – 2012-03-15 02:34:32