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块?在发生异常时,您希望发生什么?你想让它归还所有的公关吗