Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试catch v/s if语句_C#_If Statement_Try Catch_Clr - Fatal编程技术网

C# 尝试catch v/s if语句

C# 尝试catch v/s if语句,c#,if-statement,try-catch,clr,C#,If Statement,Try Catch,Clr,我想将列从一个表添加到另一个表。 这里,colName是字符串变量,它是从开发人员提供的硬编码参数中提取的。 因此,colName不正确的可能性非常小。 我希望避免由于colName错误而引发异常 实现同样目标的最佳方法是什么? 我想到了下面的两个选择 if(_table.Columns.Contains(colName)) { AddColumnToTable(_table.Columns[colName]); } 或 首先,当这件事发生时,整个世界都在里面死去了: catch {

我想将列从一个表添加到另一个表。 这里,colName是字符串变量,它是从开发人员提供的硬编码参数中提取的。 因此,colName不正确的可能性非常小。 我希望避免由于colName错误而引发异常

实现同样目标的最佳方法是什么? 我想到了下面的两个选择

if(_table.Columns.Contains(colName))
{
     AddColumnToTable(_table.Columns[colName]);
}


首先,当这件事发生时,整个世界都在里面死去了:

catch { }
但我离题了

真正的问题不是你是否应该使用if vs.try,真正的问题是:

如果该列无法添加,那么该怎么办

如果这是一个预期的场景,基本上没有什么大不了的,并且逻辑可以在不添加列的情况下继续,那么If肯定是一条路要走。正如在对问题的评论中所提到的,测试然后采取行动

然而,如果这不是一个预期的场景,而且这是一个大问题,并且逻辑无法有意义地继续,那么抛出一个异常。不要抓住它,忽略它。让应用程序级别的消费代码捕获并处理它,可能会通知用户或记录错误,甚至可能试图以某种方式更正错误

或者,如果此代码位于应用程序级别,请在此处捕获并处理它。关键是。后者是一个简单的catch块,前者是以有意义的方式响应错误所需的自定义逻辑

您甚至可以向异常添加更多信息。例如:

try
{
    // perform some operation
}
catch (SpecificException ex)
{
    throw new CustomException("Failed to perform Operation X in the context of Y.", ex);
}

这在诊断无法附加调试器的生产系统时非常有用。特定的异常类型、有用的错误消息,当然还有原始异常的技术细节都是必要的工具。

仅根据您提供的信息,只有一个结论:

if(_table.Columns.Contains(colName))
{
    AddColumnToTable(_table.Columns[colName]);
}
因为替代方法是使用空catch块进行异常处理。这基本上意味着您不打算在找不到colName的情况下做任何事情。 但是,如果您的代码被精简为任意示例,而您只是清除了catch块以使文章更简洁,那么结论可能会有所不同

这样做:

catch { }
无论如何都应该避免

根据这一说法:

这里,colName是字符串变量,它是从开发人员提供的硬编码参数中提取的

您可以选择在代码中包含断言而不是异常,因为传递错误的列名可能被视为应用程序错误。 因为您不想预见异常,所以我认为断言是一个不错的选择。这将产生以下代码:

if(_table.Columns.Contains(colName))
{
    AddColumnToTable(_table.Columns[colName]);
}
else Debug.Assert(false,"Column name is wrong, please correct calling code.");
或更多浓缩物:

Debug.Assert(_table.Columns.Contains(colName),
             "Column name is wrong, please correct calling code.");
AddColumnToTable(_table.Columns[colName]);

如果可以使用if,请不要使用try/catch。这是代码可读性和可维护性的问题

如果你重视性能,那么,在这种情况下,你可能会考虑失败的可能性。您的库可能会执行以下操作:

void AddColumn(string columnName, Column column)
{
    if(this.Columns.Contains(columnName))
         throw new DuplicateColumnException();
    else
         this.Columns.Add(columnName, column);
}
这意味着您的if将添加第二个Contains调用,根据其复杂性,抛出异常可能比调用第二个check更好

解决此问题的最佳方法是找到设置列的方法:

void SetColumn(string columnName, Column column)
{
    if(this.Columns.Contains(columnName))
         this.Columns[columnName] = column;
    this.Columns.Add(columnName, column);
}
或者简单地说:

void SetColumn(string columnName, Column column)
{
    this.Columns[columnName] = column;
}

在过去,我写过一些游戏,游戏的表现非常重要。我发现在catch语句被命中的情况下,会对性能产生严重影响。事情真的很慢。我想这是因为它必须捕获关于出错原因的所有细节,并尝试在catch语句中输出这些信息,这些都是非常低效的东西。我会尽可能避免使用try语句。最好是使用if语句来捕获这类内容,尤其是在性能很重要的情况下。

最好先测试,然后行动,而不是盲目行动,然后抓住。如果可能的故障非常常见,那么通常会更快AddColumntTable是否会引发异常?如果没有,那么try-catch就没有什么帮助了…@Mivaweb我会说它更像是一个抛出的_table.Columns[],我同意@xanatos。值得注意的例外是竞争条件,例如:if File.Existsf File.Deletef.Eric Lippert具有。这将属于“愚蠢的”,另一天,关于例外的另一个主观问题和另一个我完全不同意的答案。不要让代码抛出一个异常,然后代码的其他方面不得不猜测原因并采取行动。在这种情况下,如果列存在是一个大问题,那么抛出您自己的强制列x不存在并且无法添加到表异常中,这将尽可能详细说明为什么这是一个大问题,在else中,“我们不是让一个模糊的元素不存在,而是让例外从它的上下文中冒泡出来。@DavidArno:我认为我们又一次未能理解彼此的观点,我怀疑我们比你想象的更同意彼此的观点。”。为异常添加有意义的上下文绝对是一个好主意,我不鼓励这样做
在我的回答中或任何地方。关键是,如果代码不是正确的抽象级别来处理错误,那么应该在使用代码时出现异常。无论那个异常是内置的还是自定义的,差别都很小。我只想阻止代码中断并继续执行,即使出现异常occure@VishalSonavane:在这种情况下,听起来这是一个预期的场景,您希望使用if语句来测试该条件。这样想吧。。。如果无法添加列不是异常事件,则不应涉及异常。永远不要使用异常来驱动逻辑,只使用它们来停止特定操作的执行。当我看到抛出新的。。。然后注意到它被标记为C,而不是C++不,我不想在catch块中做任何事情。即使发生异常,我也要继续执行。基本上,发生异常的可能性非常小。这会影响吗?使用断言只会影响调试生成,生产生成将继续。如果您甚至不希望在调试构建中使用断言,那么If语句最适合您。
void SetColumn(string columnName, Column column)
{
    this.Columns[columnName] = column;
}