Nee*_*eel 14 c# vb.net error-handling vb.net-to-c#
如果我为我的C#代码添加空catch块,它是否等同于VB.NET的"On Error Resume Next"语句.
try
{
C# code;
}
catch(exception)
{
}
Run Code Online (Sandbox Code Playgroud)
我问这个的原因是因为我必须将VB.NET代码转换为C#,旧代码有~200"On Error Resume Next"语句虽然我try {} catch {}在我的新代码中使用了正确的,但是有一个更好的选择?
Tim*_*ora 19
我发现VB程序员常常On Error Resume Next在(坏)习惯中散布许多语句.我的建议是从没有抑制异常开始,看看实际上有什么破坏.可能没有您想象的那么多问题.相反,您可以做的回归测试越多越好; 可能存在一些仅在忽略错误时才起作用的边缘情况.
最终,您需要决定错误处理策略,是否在许多try/catch块中优雅展开,或者让错误渗透到顶级处理程序(两种策略都有其用途).
如果您最终必须禁止某些异常以满足截止日期,那么至少要记录这些异常,以便下一个处理代码的开发人员不会被空的烧毁try/catch.
虽然有时这是可以接受的,但通常它表示代码气味.如果您100%确定要吞下已发生的异常,您可以按照自己的方式执行此操作,但通常如果抛出异常,您应该执行某些操作.
通常,您可以使用设计良好的代码实现相同的结果.如果您目前遇到特定错误,请将其添加到您的问题中,但如果您只是出于好奇而不是,那就没有相应的问题,这是一件好事.
您需要On Error Resume Next逐个分析语句,看看它们的用途是什么.有些可能只是草率的代码,但On Error Resume Next在Visual Basic 6.0代码中有正当理由.
为什么要On Error Resume Next在Visual Basic 6.0代码中使用的一些示例:
检查Visual Basic 6.0集合中是否存在给定键.执行此操作的唯一方法是按键访问元素,并处理在密钥不存在时引发的错误.转换为.NET时,可以通过检查密钥是否存在来替换它.
将字符串解析为整数.在.NET中,您可以使用TryParse.
不,不一样。
当使用On Error Resume Next时,如果发生错误,VB将跳至下一行。使用try / catch时,如果发生错误(异常),则执行跳转到catch块。
小智 5
尽管On Error Resume Next滥用的程度肯定超过了合法使用的程度,但即使在VB.NET中,在某些地方它也会有所帮助。
考虑一个为大量Excel属性分配值的程序,例如所有打印机参数的默认值-Excel中有不计其数的打印机参数。更高版本的Excel可能具有早期版本不支持的属性,并且弄清楚每个版本支持哪些属性并非易事。如果该属性存在,则程序应分配一个值,但如果使用旧版本的Excel,则应忽略该属性。
使用VB.NET进行此操作的“正确”方法是确定每个Excel版本都支持哪些打印机属性,读取正在使用的版本,然后仅分配给在该版本中实现的属性。这将需要大量的研究和一些代码,而这些都没有多大好处。On Error Resume Next将是一个更实际的解决方案。
而且,不幸的是,我现在正面临着这个问题。我要尝试的解决方法是编写一个子例程,该例程仅将一个值分配给另一个,而忽略错误。我将这个子路由称为每个赋值语句。不太可怕,但也没有那么好。
“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();
Run Code Online (Sandbox Code Playgroud)
如果 xml 通常具有 Field3 的值但有时没有;我将收到一个令人讨厌的错误,即该表不包含该字段。如果不是,我可以不在乎,因为它不是必需的数据。在这种情况下,ON Error Resume Next 将允许我忽略该错误,并且我不必围绕每一行代码进行编码,设置变量检查表、行和列组合的存在与包含方法。这是一个小例子;我可能会从大文件中提取数千个表、列、行组合。此外,这里假设必须以这种方式填充字符串变量。这是未处理的代码,会有麻烦。
考虑一个 VB.NET 和 ON Error Resume Next 实现:
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()
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,只需要处理一种可能的错误情况;即使在处理第三个错误之前有两个错误。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);
}
Run Code Online (Sandbox Code Playgroud)
尽管在 try/catch 块中,lambda 函数正在检查从由 xml 动态填充的数据集中提取的每个表、行、列组合是否存在。这可以逐行检查,但需要大量多余的代码(这里我们有相同数量的执行代码,但要维护的编写代码要少得多)。不幸的是,这可能被认为是“单行函数”的另一种不好的做法。在 lambdas 和匿名函数的情况下,我打破了这条规则。
由于 .NET 提供了许多方法来检查对象的状态;On Error Resume Next 对 VB 专家来说并不像 .NET 之前那样重要,但仍然很好用;尤其是当你在编码一些东西时,如果不快速和肮脏的编码会浪费时间。对您来说,Java 转换为 C#;加入 Microsoft 世界,不要再假装如果 10000 名中级 Java 和 C# 程序员这么说,那一定是真的,因为如果一位顶级 Microsoft Guru(例如创建 VB 语言和 .NET 的任何一位)显然与您在他们自己开发.NET,这是假的,你看起来很愚蠢。我想要我可以在 C#、VB 和 F# 以及我需要使用的任何其他语言中获得的所有功能。C# 很优雅,但 VB 更先进,因为它的任期更长,但它们都做“同样的事情” 并使用相同的对象。好好学习它们,或者请不要在比较对话中对其中任何一个进行评论;对于我们这些自 90 年代中期以来一直在高水平使用 Microsoft 技术的人来说,这令人作呕。
| 归档时间: |
|
| 查看次数: |
33992 次 |
| 最近记录: |