“On Error Resume Next”允许“内联错误处理”,这是 VB 中的专家级错误处理。这个概念是逐行处理错误,或者根据错误执行操作,或者在有益时忽略错误 - 但按照编写代码的顺序运行代码而不使用代码跳转。
不幸的是,许多新手使用“On Error Resume Next”通过忽略所有错误来向使用他们的应用程序的人隐藏他们的能力不足或懒惰。 Try/catch 是块级错误处理,在.NET 之前的世界中,它在设计和实现上是中间的。
VB.NET 中“On Error Resume Next”的问题在于,它在执行代码的每一行都加载了 err 对象,因此比try/catch 慢。我有点担心这个论坛检查并推广了一个愚蠢的答案,声称使用 On Error Resume Next 是一个坏习惯和代码垃圾。这是一个 C# 论坛; C# 程序员真的应该用它来研究他们不精通的另一种语言吗?
https://msdn.microsoft.com/en-us/library/aa242093(v=vs.60).aspx
据说没有真正 VB 经验的中级 C# 程序员不应该因为他们对另一种“Microsoft Net”语言的奇怪蔑视而试图让 C# 变得愚蠢和功能有限,请考虑以下代码:
//-Pull xml from file and dynamically create a dataset.
string strXML = File.ReadAllText(@"SomeFilePath.xml");
StringReader sr = new StringReader(strXML);
DataSet dsXML = new DataSet();
dsXML.ReadXml(sr);
string str1 = dsXML.Tables["Table1"].Rows[0]["Field1"].ToString();
string str2 = dsXML.Tables["Table2"].Rows[0]["Field2"].ToString();
string str3 = dsXML.Tables["Table3"].Rows[0]["Field3"].ToString();
string str4 = dsXML.Tables["Table4"].Rows[0]["Field4"].ToString();
string str5 = dsXML.Tables["Table5"].Rows[0]["Field5"].ToString();
如果 xml 通常有 Field3 的值但有时没有;我将收到一个恼人的错误,即表格不包含该字段。如果不是,我可以不在乎,因为它不是必需的数据。在这种情况下,ON Error Resume Next 将允许我忽略错误,并且我不必围绕每一行代码编写代码,设置变量检查表、行和列组合是否存在包含方法。这是一个小例子;我可能会从大文件中提取数千个表、列、行组合。此外,这里假设必须以这种方式填充字符串变量。这是未处理的代码,会有麻烦。
考虑一个 VB.NET 和 ON 错误恢复下一个实现:
On Error Resume Next
'Pull Xml from file And dynamically create a dataset.
Dim strXML As String = File.ReadAllText("SomeFilePath.xml")
Dim srXmL As StringReader = New StringReader(strXML)
Dim dsXML As DataSet = New DataSet()
dsXML.ReadXml(srXmL)
'Any error above will kill processing. I can ignore the first two errors and only need to worry about dataset loading the XML.
If Err.Number <> 0 Then
MsgBox(Err.Number & Space(1) & Err.Description)
Exit Sub 'Or Function
End If
Dim str1 As String = dsXML.Tables("Table1").Rows(1)("Field1").ToString()
Dim str2 As String = dsXML.Tables("Table2").Rows(2)("Field2").ToString()
Dim str3 As String = dsXML.Tables("Table3").Rows(3)("Field3").ToString()
Dim str4 As String = dsXML.Tables("Table4").Rows(4)("Field4").ToString()
在上面的代码中,只需要处理一种可能的错误情况;即使在处理第三个错误之前有两个错误。 RAD 开发需要 On Error Resume Next。 C# 是我选择的语言,但由于许多原因,它不像 VB 那样是一种 RAD 语言。我希望所有程序员都意识到几种主要语言(即 C)只是运行并且不会因未处理的错误而停止执行;在他们认为必要的地方检查他们是开发人员的工作。 On Error Resume Next 是微软世界中最接近该范式的东西。
幸运的是,.NET 确实提供了许多高级选择来处理这些情况;我避开了包含。因此,在 C# 中,您必须提高语言知识水平,并且根据 C# 语言规范正确地解决此类问题。考虑一种处理大量重复代码行的解决方案,这些代码行可能包含恼人的丢弃错误:
try
{
if (!File.Exists(@"SomeFilePath.xml")) { throw new Exception("XML File Was Not Found!"); }
string strXML = File.ReadAllText(@"SomeFilePath.xml");
StringReader sr = new StringReader(strXML);
DataSet dsXML = new DataSet();
dsXML.ReadXml(sr);
Func<string, string, int, string> GetFieldValue = (t, f, x) => (dsXML.Tables[t].Columns.Contains(f) && dsXML.Tables[t].Rows.Count >= x + 1) ? dsXML.Tables[t].Rows[x][f].ToString() : "";
//-Load data from dynamically created dataset into strings.
string str1 = GetFieldValue("Table1", "Field1", 0);
string str2 = GetFieldValue("Table2", "Field2", 0);
string str3 = GetFieldValue("Table3", "Field3", 0);
//-And so on.
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
尽管在 try/catch 块中,lambda 函数正在检查从由 xml 动态填充的数据集中提取的每个表、行、列组合是否存在。这可以逐行检查,但需要大量多余的代码(这里我们有相同数量的执行代码,但要维护的书面代码要少得多)。不幸的是,这可能被认为是“单线功能”的另一种不良做法。在 lambdas 和匿名函数的情况下,我打破了这条规则。
由于 .NET 提供了很多方法来检查对象的状态; On Error Resume Next 对 VB 专家来说并不像在 .NET 之前那样重要,但仍然很好用;尤其是当您编写的代码会浪费时间而不是快速和肮脏的代码时。对你来说,Java 转换为 C#;加入微软世界,不要再假装如果 10000 名中级 Java 和 C# 程序员都这么说,那一定是真的,因为如果一位*微软大师(例如任何一位创建 VB 语言和 .NET 的人)显然在他们开发 .NET 本身,这是错误的,你看起来很愚蠢。我想要在 C#、VB 和 F# 以及我需要使用的任何其他语言中获得的所有功能。 C# 很优雅,但 VB 更进化,因为它的任期更长,但它们都做“相同的事情”并使用相同的对象。把它们都学好,或者请不要在比较对话中评论任何一个;对于我们这些从九十年代中期就在高水平使用微软技术的人来说,这真是令人作呕。