C# try/catch并返回值

C# try/catch并返回值,c#,methods,exception-handling,return,try-catch,C#,Methods,Exception Handling,Return,Try Catch,我有一个返回列表的方法。现在我想知道如何正确放置try/catch块。如果我将return语句放在try中,则会出现错误 并非所有代码路径都返回值 如果我在catch之后放置(就像我现在做的那样),它将返回产品,即使在异常之后也是如此。那么,最好的方法应该是什么呢 方法如下: public List<Product> GetProductDetails(int productKey) { List<Product> products = new List<P

我有一个返回
列表的方法。现在我想知道如何正确放置
try/catch
块。如果我将
return
语句放在
try
中,则会出现错误

并非所有代码路径都返回值

如果我在
catch
之后放置(就像我现在做的那样),它将返回
产品
,即使在
异常之后也是如此。那么,最好的方法应该是什么呢

方法如下:

public List<Product> GetProductDetails(int productKey)
{
    List<Product> products = new List<Product>();
    try
    {
       using (SqlConnection con = new SqlConnection(_connectionString))
       {
         SqlCommand cmd = new SqlCommand("usp_Get_ProductDescription", con);
         cmd.CommandType = CommandType.StoredProcedure;
         cmd.Parameters.AddWithValue("@riProductID", productKey);
         con.Open();
         using (SqlDataReader reader = cmd.ExecuteReader())
         {
           while (reader.Read())
           {
             Product product = new Product(reader["Name"].ToString(), reader["Code"].ToString());
             products.Add(product);
           }
         }
       }
     }
     catch { }
     return products;
}
公共列表GetProductDetails(int-productKey)
{
列表产品=新列表();
尝试
{
使用(SqlConnection con=newsqlconnection(_connectionString))
{
SqlCommand cmd=newsqlcommand(“usp\u Get\u ProductDescription”,con);
cmd.CommandType=CommandType.storedProcess;
cmd.Parameters.AddWithValue(“@riProductID”,productKey);
con.Open();
使用(SqlDataReader=cmd.ExecuteReader())
{
while(reader.Read())
{
产品产品=新产品(读卡器[“名称”].ToString(),读卡器[“代码”].ToString());
产品。添加(产品);
}
}
}
}
捕获{}
退货产品;
}

目前,如果抛出异常,您不会返回任何内容。 使用
try,catch,finally
。(您可能想查看更多官方信息)


因此,如果将
return
语句放入
finally
部分,即使抛出异常,也会返回列表…

此时,如果抛出异常,则不会返回任何内容。 使用
try,catch,finally
。(您可能想查看更多官方信息)


因此,如果将
return
语句放入
finally
部分,即使抛出异常,也会返回列表…

删除完整的
Try
Catch
块。显然,您无法在
GetProductDetails
方法中处理异常,所以就让它们被抛出吧

但是,调用代码可以做出以下决定:

IList<Product> products = null;

try
{
    products = GetProductDetails(3);
}
catch(Exception ex)
{
    // Here you can make the decision whether you accept an empty list in case of retrieval errors.
    // It is the concern of this method, not of the ProductDetails method.
    // TODO: Use logging
    products = new List<Product>();
}
IList products=null;
尝试
{
products=GetProductDetails(3);
}
捕获(例外情况除外)
{
//在这里,您可以决定是否接受空列表以防检索错误。
//这是此方法的问题,而不是ProductDetails方法的问题。
//TODO:使用日志记录
产品=新列表();
}

我可以想象,如果必须使用
GetProductDetails
方法在每个方法中编写此代码,感觉就像是代码重复。但是考虑一下,当你有X实现时,你想对不能获得产品细节做出不同的反应。你必须想出变通办法。您甚至可能会遇到难以排除的奇怪错误。

删除完整的
Try
Catch
块。显然,您无法在
GetProductDetails
方法中处理异常,所以就让它们被抛出吧

但是,调用代码可以做出以下决定:

IList<Product> products = null;

try
{
    products = GetProductDetails(3);
}
catch(Exception ex)
{
    // Here you can make the decision whether you accept an empty list in case of retrieval errors.
    // It is the concern of this method, not of the ProductDetails method.
    // TODO: Use logging
    products = new List<Product>();
}
IList products=null;
尝试
{
products=GetProductDetails(3);
}
捕获(例外情况除外)
{
//在这里,您可以决定是否接受空列表以防检索错误。
//这是此方法的问题,而不是ProductDetails方法的问题。
//TODO:使用日志记录
产品=新列表();
}

我可以想象,如果必须使用
GetProductDetails
方法在每个方法中编写此代码,感觉就像是代码重复。但是考虑一下,当你有X实现时,你想对不能获得产品细节做出不同的反应。你必须想出变通办法。您甚至可能会遇到难以排除的奇怪错误。

这取决于在特殊情况下应该发生什么。如果发生这种情况的原因“不足以”让应用程序崩溃,或者如果您能够适当地处理该异常,那么您可以使用当前的appraoch-但是您应该在catch子句中至少留下一条日志消息,其中包含已抛出的错误:

catch (Exception e) 
{ 
    log.Info(e.Message);
}
通过这种方式,您可以获得列表中的所有结果,但导致任何异常的结果除外。您可以简单地继续使用您得到的所有结果并忽略那些错误的结果(假设您以任何方式记录它们)


如果这是一个真正意外的行为(这是异常的预期行为,这就是它们被称为异常的原因),您应该从方法中删除所有这些try/catch,并处理方法之外的任何异常,正如Maurice已经提到的那样

这取决于在特殊情况下应该发生什么。如果发生这种情况的原因“不足以”让应用程序崩溃,或者如果您能够适当地处理该异常,那么您可以使用当前的appraoch-但是您应该在catch子句中至少留下一条日志消息,其中包含已抛出的错误:

catch (Exception e) 
{ 
    log.Info(e.Message);
}
通过这种方式,您可以获得列表中的所有结果,但导致任何异常的结果除外。您可以简单地继续使用您得到的所有结果并忽略那些错误的结果(假设您以任何方式记录它们)


如果这是一个真正意外的行为(这是异常的预期行为,这就是它们被称为异常的原因),您应该从方法中删除所有这些try/catch,并处理方法之外的任何异常,正如Maurice已经提到的那样

有史以来最糟糕的错误处理。为什么要使用空的catch块?如果发生异常,您希望发生什么?您想让它退回到目前为止找到的所有产品吗?跳过任何导致错误的产品?返回一个空列表?返回null?有史以来最糟糕的错误处理。为什么要使用空的catch块?在发生异常时,您希望发生什么?你想让它归还所有的公关吗