量作用域:
•Global-level variables were accessible to the entire application. •Module-level variables were accessible in the code file (form, class, or module) in which they were declared. •Local variables were accessible only in the routine in which they were declared. •全局变量在整个程序有效。 •模块级变量在声明代码所在的文件(窗体、类、模块)。 •本地变量只在声明他们的过程中有效。
In .NET, there is a fourth type of scoping—block-level scoping. Variables declared within a block, such as a Try block or For/Next block, are only accessible within the block. If the declaration of the User object had been inside of the Try block, the Finally block would not be able to reference the variable. So object variables that will need to be disposed in the Finally block must be declared outside of the Try block. 在 .Net 里,这属于第四种。变量在模块中被声明,就像 Try 模块和 For/Next 模块,变量就在模块中起作用。 如果 User 对象在 Try 模块中被声明,那么在 Finally 他将不能被访问。因此,对象的值就会在 Finally 模块中被垃圾收集机制去除,显然它需要在 Try 模块意外被声明。
Throwing Exceptions 丢出异常
One of the reasons that exceptions are not called errors is that the term error frequently implies a coding mistake. An exception is any violation of a routine''''s implicit assumptions. The .NET Framework will throw exceptions to your application if your code violates any of the .NET Framework implicit assumptions. For example, the .NET Framework assumes that a divisor will be a non-zero number. If your code attempts to divide by 0, an exception will be thrown. You can then catch these exceptions using the Try/Catch block. 异常部叫做错误的其中一个原因,是因为错误的特征通常也包含了译码的错误。异常是任何违背了程序固有的假设。只要你的代码中含有任何违反.Net 框架的固有假设的东西,.Net 框架就会丢出一个异常。例如,.Net 框架认为除数是一个非0的值。如果你的代码试图把0 当作除数,一个异常便会被丢出。你可以在 Try/Cathc 模块中捕获它。
When writing your routines, you should follow the same guidelines and throw exceptions when any implicit assumption is violated. To throw an exception, use the Throw statement and throw a new instance of the appropriate exception class. (See the online help for the list of .NET exceptions that youcan throw.) For example, the ValidateLogin method makes the assumption that it should receive non-empty values as the parameters. If the values are empty, it should throw an ArgumentOutOfRange exception. 在你编写程序的时候,你可以根据指导性的原则,在系统的各种固有假设被违反后丢出一个异常,使用 Throw 语句丢出一个异常类。举个例子,ValidateLogin 事件假定它收到的参数种不会有空值。如果空值出现了,他就会丢出一个 ArgumentOutOfRange 异常。
Public Function ValidateLogin(ByVal sUserName As String, _ ByVal sPassword As String) As Boolean If sUserName.length=0 OrElse sPassword.Length=0 Then Throw New ArgumentOutOfRangeException("Username and password are required.") End If '''' Code to validate login here Return True End Function
This Throw statement creates a new instance of the ArgumentOutOfRangeException and defines the message text. When this statement is executed, the exception is thrown. The code following the Throw statement is not executed, but rather the .NET runtime looks for a Try/Catch block. If the current code is not in a Try block, the .NET runtime looks up the call stack to see if the code that called this method is in a Try block. If it finds a Try block, it then looks for an associated Catch block. If the .NET runtime finds an appropriate Try/Catch block, it executes the code in the Catch block. Otherwise, it displays the unhandled exception message and terminates the application. Note As the .NET runtime looks for associated Try blocks up the call stack, it will execute any code in the associated Finally block of the Try blocks before continuing up the call stack. 这个异常语句创建了一个 ArgumentOutOfRangeException 并定义了一个消息,当这个语句被执行,异常就会丢出。Throw 后面的语句将不会被执行,但 .Net 运行时会自动寻找 Try/Catch 模块,如果当前不在一个Try 模块中,.Net 运行时查找 Call 堆栈以检查看调用自身的事件中是否存在 Catch 模块。如果 .Net 运行时发现了一个 Try/Catch 模块,执行 Catch 模块中的代码。否则,显示一个错误信息并终止程序。 提醒:当.Net 运行时从堆栈中发现 Try 模块,在程序继续运行之前,他会先把 Try 对应的 Finally 模块中的所有代码执行完毕。
In addition to throwing .NET exceptions, you may find that you want to define your own custom exceptions. In the login example, in addition to throwing the ArgumentOutOfRangeException you may want to throw a custom exception if the username is not valid and a different custom exception if the password is not valid. 另外,对于.Net 的异常,你可以定义一个自定义的异常。以登录的为例,你可以在ArgumentOutOfRangeException 以外为不合法的用户名和密码各自附上一个自定义的异常。
To create a custom exception, you can create your own exception class. To ensure that it behaves as a .NET exception, your new exception class should inherit from one of the .NET exception classes. The recommended class to use for your inheritance is the ApplicationException class. For example, the UsernameNotFoundException class would look like this: 要创建一个自定义的异常,你可以自定义一个异常类。为了确保它是一个 .Net 的异常,你的异常类应该从一个 .Net 异常类中继承而来。其中一个比较好的继承对象是 ApplicationException 类。就像下面例子中的UsernameNotFoundException类:
Public Class UsernameNotFoundException : Inherits ApplicationException Public Sub New() MyBase.New() End Sub Public Sub New(ByVal message As String) MyBase.New(message) End Sub Public Sub New(ByVal message As String, ByVal innerEx As Exception) MyBase.New(message, innerEx) End Sub End Class
When using inheritance, the new class automatically has all of the properties and methods of the inherited class. So, the UsernameNotFoundException class has all of the standard ApplicationException properties, such as the message and call stack. The new class does not inherit any of the constructors of the inherited class; hence the need for this class to have its own constructors. The ApplicationException class supports three constructors: 使用继承的时候,新的类会自动从父类继承了所有的属性。因此,UsernameNotFoundException 类会拥有 ApplicationException 类的所有属性,例如消息和调用。 新类不会继承父类的参数表,因此你需要为新的类定义参数表。ApplicationException 支持以下三种参数结构。
•One with no parameters 没有参数 •One with just the message parameter 只有一个消息参数 •One with both a message and an inner exception 一个消息和一个内部的异常
The last constructor is used in the case when the code catches an exception and then re-throws it as a different exception, but wants to retain the original exception information. 最后一个参数结构是用于代码截获一个异常后再重新丢出一个异常,但又想保持原有的异常信息。
You can also add custom properties and methods to your new exception class. For example, you could add a username property to your exception class so that you could log any exceptions and include the username of the user that had the exception. The routine can throw custom exceptions as follows: 同样地你可以为你的新异常自定义属性和事件,例如,你可以为你的异常加入一个 username 属性用来记录所有产生异常的用户的信息。 丢出自定义异常的代码如下:
Public Function ValidateLogin(ByVal sUserName As String, _ ByVal sPassword As String) As Boolean If sUserName.length=0 OrElse sPassword.Length=0 Then Throw New ArgumentOutOfRangeException("Username and password are required.") End If '''' Code to locate the user record here If iUserRecordID = 0 Then Throw New UsernameNotFoundException("Invalid username") End If '''' Code to retrieve the password from the user record here If sPassword <> sUserRecordPassword Then Throw New PasswordInvalidException("Invalid password") End If Return True End Function
This routine then throws either a .NET exception or a custom exception if any of the routine''''s implicit assumptions are violated. Notice that there is no Try/Catch block around this code. You will find that most of your methods won''''t need Try/Catch blocks. Rather, all of your event procedure code will be your line of defense, catching any exceptions thrown by any of the methods called by those event procedures. 这个程序中,如果出现了任何程序错误,.Net 的异常和自定义的异常会同时被丢出。 注意,上面的代码中并没有 Try/Catch 模块,你会发现你的大多数方法都不需要 Try/Catch 模块。就是说,你所有的事件程序是就是你的保护线,由事件引起的方法对有丢出的异常都会被截获。
Catching Custom Exceptions 捕获错误
The Try/Catch block code shown at the beginning of this article provided a generic exception handler using a generic exception filter—ex as Exception. This filter would catch any .NET exception or custom exception that inherited from a .NET exception. In the login example, the generic exception filter would correctly catch any exception thrown from the ValidateLogin method. 在这编文章的开头我们在Try/Catch 模块中演示了一个一般的异常提供的一个参数 –ex。通过这个参数可以捕捉所有的.Net 异常和继承.Net异常的自定义异常。在登录例子中,这个一般的异常参数可以正确地捕获从 ValidateLogin 事件丢出的异常。
There may be cases, however, when the code needs to perform different processes depending on which exception was thrown. A Try/Catch block can contain any number of Catch blocks with more explicit exception filters that can catch specific custom or .NET exceptions and perform processing for each type of exception. 可能在某些案例中,当程序需要根据被丢出异常的内容进行不同的处理时,一个 Try/Catch 模块可以包含很多个Catch模块加上不同的参数便可以获得和处理各种自定义或者.Net异常。
Private Sub cmdLogin_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles cmdLogin.Click Dim oUser As User() Dim bValid as Boolean Try oUser = New User() bValid = oUser.ValidateLogin(txtUserName.Text, txtPassword.Text) If bValid then DialogResult = DialogResult.OK End If Catch ex As UsernameNotFoundException MessageBox.Show(ex.Message) txtUserName.Focus() Catch ex As PasswordInvalidException MessageBox.Show(ex上一页 [1] [2] [3] 下一页 |