在Visual Basic中,我写只是On Error Resume Next
在我的程序和错误的头在整个项目受到打压。
在这里,在C#我想这个功能非常多。 通常try-catch
处理的每一个过程不仅非常耗时的,它带来的不期望的效果。 如果遇到错误,即使处理,代码不会出现的点继续 。 随着On Error Resume Next
,将代码从错误的角度继续,只是跳过函数调用导致错误。
我没有深入地参与用C#还,但也许有在C#中存在比原始一个更好的错误处理try-catch
。
我也想有在出现错误以及在我的错误消息的行号模块或函数名。 该Exception
类不提供据我知道的功能。 任何想法(管理,当然,不涉及我自己的应用程序的任何过程的类)?
你如何处理这些错误在更大的项目? 我希望我没有到加try-catch
每个方法。 不知怎的,C#抛出许多错误 - 这似乎是典型的语言。
我的解决方案,我发现重新解决我的几个问题:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[STAThread]
static void Main()
{
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); //setup global error handler
Application.Run(new Form1());
}
private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("Unhandled exception: " + e.Exception.ToString()); //get all error information with line and procedure call
Environment.Exit(e.Exception.GetHashCode()); //return the error number to the system and exit the application
}
private void button1_Click(object sender, EventArgs e)
{
string s = ""; s.Substring(1, 5); //Produce an error
}
}
好像什么都没有发生的事情错误后继续编程是一个可怕的方式。
不能工作在该帐户的新的平衡? 这没关系,我们只是将其存储为0。没有人会知道,对不对?
try
/ catch
块实际上应该是比较少见的,因为有你真的可以从恢复相对较少的错误。 通常,你应该有一个try / catch块一些逻辑操作的顶部,这样,如果失败,您可以通知用户,并继续与其他完全不同的操作 - 或完全终止应用程序,这取决于你是什么样的应用写作。 (Web应用程序这里有一个很好的例子:你可以请求失败,希望照顾,你没有讨厌的持续性的副作用,并继续处理其他请求。)
哪里有地方,你合理地期望你可以从错误中恢复,赶上那些特定的异常,并适当地处理它们(如回落至写入如果写入到数据库失败的文件)。 同样,这些都是比较寥寥可数。 如果你发现自己写一个try
/ catch
在每一个方法块(或者甚至每类),那么你很可能例外处理不当。
我也想有地方出错,我的错误信息发生以及行号模块或函数名。 Exception类不提供尽可能我经历过的功能。
是的,它确实。 栈跟踪显示的类型,方法和行号(如果有的话),用于组中的每个帧...以及(希望有用)消息,当然。 哦,并有可能嵌套的例外太多,如果故障是另一个引起的。
不知怎的,C#在执行引发许多错误总是,这是典型的语言。
不,这只是意味着你就错了。
没有。
谈到作为一个前VB程序员,请让我向你保证:这是以往任何时候都加入到以往任何语言最坏,最被滥用的功能。 这里的想法,而不是:
- 编写的代码不会出错......除非有事, 实际上是一个问题 。 这可能包括检查你的假设 ,你做的事情之前; 大:这样做
- 唯一需要注意的问题你期待; 吞咽所有的错误只是要求大量问题
正如乔恩已经指出的,它实际上是相当罕见的需要异常处理所有的地方。 通常你只是让一个异常泡到一个更高的来电者,因为一些不好就这样发生了 。 而当我有一个try
,它是更常见的try
/ finally
(不是try
/ catch
) -与using
和lock
(ETC)是那些方便的特殊情况。
事实上,例外情况是比较例外,他们没有发生的事情。 当他们有这样的事情,你想知道他们发生了,要么处理它们或关闭过程。 大多数时候让一个异常未处理去的会导致非常意外的结果。
不,你不能。 这是不可能在C#(和不应该在任何其他语言)。
这在VB中的真正用途是在代码中的某些部分处理错误,就像try / catch
。 你启用它,请与Err.Number <> 0
,做你的工作,并恢复与错误流On Error GoTo 0
或重定向到如下处理错误或继续执行不同的通道的标签On Error GoTo someErrorCase:
您必须学会单独或与一个人不这样做的正确的方式进行编程。 忽略错误是一个坏习惯,并不止此,它的一个可怕的事情,只是与代码遵循。 毕竟,错误是可能的。
相信我。 我是一个VB程序员,当我停下来阅读的最佳做法是有启发性。
我想补充一些,尽量使用Option Explicit
太多,这听起来就宣布所有的变量更多的工作,但它会给你的代码更有信心,因为类型检查将限制一些常见错误。
此外,C#的例外是一种非常有用的,并有可能需要的所有信息。 如果你还没有与例外本身的问题,只要打开它,并期待在其内部异常(我赶上我一直在寻找内部异常的Web开发时,因为所有的代码是在较高的水平)。
你一直在使用VB功能错了,你太幸运了,你不能在C#中使用它这样。
当使用VB中的功能,您应该每一个可能导致错误操作后检查错误状态。 在正确使用时,它并不比有代码少try...catch
周围的每一个可能导致错误操作块。
所以,如果你认为你必须做更多的错误在C#中处理,你一直在做之前太少错误处理。
“在错误继续下一步”允许“内联错误处理”,这是专家级的错误在VB中处理。 这个概念是,以处理线路故障线路的基础上,错误或当有益忽略错误或者执行一个动作 - 序列中,但运行的代码编写程序,而不是使用代码跳跃。
不幸的是,许多新手使用“上的错误继续下一步”隐藏使用他们的应用程序忽略所有错误的或者他们缺乏能力或出于懒惰。 try / catch语句是块级的错误处理,这在pre-.NET世界是通过设计和实施中间。
有问题“上的错误继续下一步”在VB.NET是,它加载上执行代码的每一行的ERR对象,因此,比的try / catch慢。
https://msdn.microsoft.com/en-us/library/aa242093(v=vs.60).aspx
它被说,没有真正的VB经验中间C#程序员不应该尽量保持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"].ToStrin();
string str3 = dsXML.Tables["Table3"].Rows[0]["Field3"].ToStrin();
string str4 = dsXML.Tables["Table4"].Rows[0]["Field4"].ToString();
string str5 = dsXML.Tables["Table5"].Rows[0]["Field5"].ToString();
如果XML通常有Field3的,但有时不是一个值; 我要得到该表不包含字段一个恼人的错误。 我可以不在乎,因为它不是必需的数据也不会少。 在这种情况下,错误继续下一步将让我忽略的错误,我就不必围绕每一行代码设置变量检查表,行和列的组合包含方法存在编码。 这是一个小例子; 我可能会从大文件中拉千表,列,行组合。 此外,这里假设的字符串变量,必须填充这种方式。 这是未处理的代码,并会有麻烦。
考虑一个VB.NET和ON错误继续下一步的执行情况:
On Error Resume Next
Dim strXML As String = File.ReadAllText("SomeNonExistentFileCausingAnErrorCondition.xml")
If String.IsNullOrEmpty(strXML) Then
strXML = strSomeOtherValidXmlThatIUseWhenTheFileIsEmpty
End If
Dim srXmL As StringReader = New StringReader(strXML)
Dim dsXML As DataSet = New DataSet()
dsXML.ReadXml(srXmL)
If Err.Number <> 0 Then
MsgBox(Err.Number & Space(1) & Err.Description)
Exit Sub
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()
在上面的代码,它是只需要处理一个可能的错误条件; 即使有文件加载错误。 在错误恢复下居然让我继续如预期,这让我检查字符串条件,用我的备用字符串(我很清楚,我可以检查该文件还存在,避免了文件错误,但如果它是用什么也没有一个很好的文件,strXML将是一个空字符串)。 这是对代码的其余部分的临界误差被处理,并退出该方法,因为所加载的数据集是极为重要的处理的超过它的其余部分(处理,可以通过如果需要忽略任何错误运行)。 我忽略了它,或者我可以检查错误状态,并记录它可以忽略不计的文件错误。
RAD的发展需求上的错误继续下一步。 C#是我的首选语言,但它并不像太大的RAD语言,VB的原因有很多。 我希望所有的程序员知道,几个主要的语言(如C)只运行和不停止对未处理的错误执行; 它的开发工作,以检查他们,他们认为必要的。 在错误恢复下一步是最接近于微软的世界,范式。
幸运的是,.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动态填充数据集拉每个表,行,列组合的存在。 这可以通过线检查线,但将需要大量的多余的代码(在这里我们有执行的代码,但远不如编写的代码保持相同金额)。 这不幸的是本来被视为另一种不好的做法“一号线的功能。” 我打破lambda表达式和匿名函数的情况下,这一规则。
由于.NET提供了这么多的方法来检查对象的状态; 在错误继续下一步是不是至关重要的VB专家,因为它是之前.NET但还是不错的周围; 特别是当你编码的东西,这将是浪费时间不码快速和肮脏。 谁曾经使用VB上的专家级没有人会声称,在错误继续下一步(联错误处理)是有史以来添加到语言最坏的功能。 然而,它已被广泛新手误用。
文章来源: I miss Visual Basic's “On Error Resume Next” in C#. How should I be handing errors now?