Microsoft .NET Framework 2.0 Application Development Foundation 翻译系列6(第一章:第二课公共引用类型的使用②)

 

 

How to Create and Sort Arrays如何建立和存储数组

Arrays are declared using parentheses (in Visual Basic) or square braces (in C#) as part of the declaration. As with the String type, System.Array provides members for working with its contained data. The following code declares an array with some initial data and then sorts the array:

数组在vb中声明时使用圆括号,而在c#中使用方括号进行声明。同String类型一样,System.Array提供了操作它包含数据的方法。下面代码示范使用初始化数据声明数组并存储它。

' VB
' Declare and initialize an array.
Dim ar() As Integer = {3, 1, 2}
 
' Call a shared/static array method.
Array.Sort(ar)
 
' Display the result.
Console.WriteLine("{0}, {1}, {2}", ar(0), ar(1), ar(2))
 
// C#
// Declare and initialize an array.
int[] ar = { 3, 1, 2 };
 
// Call a shared/static array method.
Array.Sort(ar);
 
// Display the result.
Console.WriteLine("{0}, {1}, {2}", ar[0], ar[1], ar[2]);

How to Use Streams如何使用Stream(流)

Streams are another very common type because they are the means for reading from and writing to the disk and communicating across the network. The System.IO.Stream type is the base type for all task-specific stream types. Table 1-5 shows some of the most commonly used stream types. In addition, network streams are found in the System.Network.Sockets namespace, and encrypted streams are found in the System.Security.Cryptography namespace.

Streams 是另一个经常使用的类型,因为它们是读写磁盘和网络间交互通信的方法。System.IO.Stream类型是所有特定Stream的基类。表1-5显示了最常使用的一些流类型。另外,网络流被定义在System.Network.Socket命名空间中,加密流被定义在System.Security.Cryptography命名空间中。

Table 1-5: Common Stream Types

System.IO Type

Use to

FileStream

Create a base stream used to write to or read from a file

用来建立一个读写文件流

MemoryStream

Create a base stream used to write to or read from memory

建立一个读写内存的流

StreamReader

Read data from the stream

从流中读取数据

StreamWriter

Write data to the stream

向流中写入数据

The simplest stream classes are StreamReader and StreamWriter, which enable you to read and write text files. You can pass a filename as part of the constructor, enabling you to open a file with a single line of code. After you have processed a file, call the Close method so that the file does not remain locked. The following code, which requires the System.IO namespace, demonstrates how to write to and read from a text file:

最简单的流类是StreamReaderStreamWriter,你可以使用它们读写文本文件。你可以使用向构造器传递一个文件名称的方式,仅使用一行代码来打开一个文件。当你操作完文件后,调用Close方法使文件不再保存被锁定的状态。下面的代码,需要System.IO命名空间,它们示范如何读写一个文本文件。

' VB
' Create and write to a text file
Dim sw As StreamWriter = New StreamWriter("text.txt")
sw.WriteLine("Hello, World!")
sw.Close
 
' Read and display a text file
Dim sr As StreamReader = New StreamReader("text.txt")
Console.WriteLine(sr.ReadToEnd)
sr.Close
 
// C#
// Create and write to a text file
StreamWriter sw = new StreamWriter("text.txt");
sw.WriteLine("Hello, World!");
sw.Close();
 
// Read and display a text file
StreamReader sr = new StreamReader("text.txt");
Console.WriteLine(sr.ReadToEnd());
sr.Close();
 

 

More Info—Streams 

For more information about streams, refer to Chapter 2, "Input/Output (I/O)."

更多关于流的信息,可以参考第二章输出/输入

How to Throw and Catch Exceptions如何抛出并捕获异常

Exceptions are unexpected events that interrupt normal execution of an assembly. For example, if your assembly is reading a large text file from a removable disk and the user removes the disk, the runtime will throw an exception. This makes sense because there is no way your assembly could continue running.

异常是打断一个正常程序集执行的未处理事件。举例来说,如果你的程序集正在从一个移动磁盘中读取一个大文本文件,而用户却移除了这个磁盘,运行时将抛出一个异常。异常对于你那个无法运行的程序集来说是很有意义的。

Exceptions should never cause your assembly to fail completely. Instead, you should plan for exceptions to occur, catch them, and respond to the event. In the preceding example, you could notify the user that the file was not available, and then await further instructions from the user. The following simplified code, which requires the System.IO namespace, demonstrates this:

异常永远不会让程序集的执行完全失败。相对的,你需要在发现异常时对它进行有计划的捕获,并处理它们。在上段的例子中,你可以通知用户文件无效,并且等待用户下一步指示。下面代码需要System.IO命名空间,示范如下:

' VB
Try
    Dim sr As StreamReader = New StreamReader("C:\boot.ini")
    Console.WriteLine(sr.ReadToEnd)
Catch ex As Exception
    ' If there are any problems reading the file, display an error message
    Console.WriteLine("Error reading file: " + ex.Message)
End Try
 
// C#
try
{
    StreamReader sr = new StreamReader(@"C:\boot.ini");
    Console.WriteLine(sr.ReadToEnd());
}
 
catch (Exception ex)
{
    // If there are any problems reading the file, display an error message
    Console.WriteLine("Error reading file: " + ex.Message);
}

In the preceding example, if any type of error occurs—including a file not found error, insufficient privileges error, or an error during the reading of the file—processing continues within the Catch block. If no problems occur, the runtime skips the Catch block.

在上面的例子中,如果产生包括文件未找到错误、权限不足错误、或者读文件错误在内的任何类型的错误,程序将会跳转到Catch语句块中继续执行。如果没有错误发生,运行时将会跳过Catch语句块。

The base Exception class is very useful and contains an error message and other application data. In addition to the base Exception class, the Framework defines hundreds of exception classes to describe different types of events, all derived from System.SystemException. Additionally, you can define your own exceptions when you need to describe an event in more detail than allowed by the standard exception classes by deriving from System.ApplicationException.

这个Exception基类是非常有用的,它包含了一个错误信息和其它的应用数据。另外,对于这个Exception基类来说,.net框架定义了数百个用来描述不同类型事件的异常类,它们都来源于System.SystemException类。同时,在你需要更详细的事件描述时,你可以通过继承扩展System.ApplicationException这个异常基类来定义自己的异常类型。

Having multiple exception classes allows you to respond differently to different types of errors. The runtime will execute only the first Catch block with a matching exception type, however, so order Catch blocks from the most-specific to the least-specific. The following code sample displays different error messages for a file not found error, an insufficient privileges error, and any other type of error that might occur:

有多种异常类可以供你在处理各式各样不同的错误类型时使用。只有在Catch块第一次匹配到异常类型时才会在运行时执行这些异常处理,所以catch块的顺序要从最具体的描述异常类型到最全面描述异常类型。下面代码例子显示不同的错误信息,包括文件未找到、权限不足、和其它可能发生的任何错误类型。

' VB
Try
    Dim sr As StreamReader = New StreamReader("text.txt")
    Console.WriteLine(sr.ReadToEnd)
Catch ex As System.IO.FileNotFoundException
    Console.WriteLine("The file could not be found.")
Catch ex As System.UnauthorizedAccessException
    Console.WriteLine("You do not have sufficient permissions.")
Catch ex As Exception
    Console.WriteLine("Error reading file: " + ex.Message)
End Try

This process is sometimes called filtering exceptions. Exception handling also supports a Finally block. The Finally block runs after the Try block and any Catch blocks have finished executing, whether or not an exception was thrown. Therefore, you should use a Finally block to close any streams or clean up any other objects that might be left open if an exception occurs. The following code sample closes the StreamReader object whether or not an exception occurs:

这个程序段有时叫做“异常过滤”,异常处理还支持一个Finally语句块。无论是否有异常被抛出,这个Finally语句块都会在TryCatch块都执行完成后运行。因此你可以用Finally块来关闭所有使用的流或清除那些已经建立但因为发生异常而没有被清除的对象。

' VB
Dim sr As StreamReader = New StreamReader("text.txt")
Try
    Console.WriteLine(sr.ReadToEnd)
 
Catch ex As Exception
    ' If there are any problems reading the file, display an error message
    Console.WriteLine("Error reading file: " + ex.Message)
Finally
    ' Close the StreamReader, whether or not an exception occurred
    sr.Close
End Try
 
// C#
StreamReader sr = new StreamReader("text.txt");
try
{
    Console.WriteLine(sr.ReadToEnd());
}
catch (Exception ex)
{
    // If there are any problems reading the file, display an error message
    Console.WriteLine("Error reading file: " + ex.Message);
}
finally
{
    // Close the StreamReader, whether or not an exception occurred
    sr.Close();
}

Notice that the StreamReader declaration was moved outside the Try block in the preceding example. This is necessary because the Finally block cannot access variables that are declared within the Try block. This makes sense because depending on where an exception occurred, variable declarations within the Try block might not yet have been executed. To catch exceptions that occur both during and after the StreamReader declaration, use nested Try/Catch/Finally blocks.

请注意,在上面的代码中,Streamreader被定义在trycatch块外。这是必须的,因为这个Finally块不能访问定义在tryCatch块中的变量。这样做的原因在于,因为一个异常的出现,定义在try块中的变量声明可能没有被执行。使用嵌套的Try/Catch/Finally块就可以捕获发生在Streamreader声明过程中或声明后的异常。

 

Typically, all code except for simple variable declarations should occur within Try blocks. Robust error handling improves the user experience when problems occur and greatly simplifies debugging problems. However, exception handling does incur a slight performance penalty. To conserve space and focus on specific topics, sample code within this book will typically not include exception handling.

特别是,除了变量声明以外的所有代码都位于try块中。当问题发生时强大的错误处理改善了用户体验和问题调试。但是,异常处理将会导致微小的性能开销。为了要保持空间和注重特定细节,书中的例子代码将不会特意包含异常处理。

Lab: Working with Reference Types练习(实验)

The following exercises reinforce knowledge of reference types, strings, and exceptions. If you encounter a problem completing an exercise, the completed projects are available on the companion CD in the Code folder.

下面练习用来加强引用类型、string、和异常的知识。如果你在完成是遇到问题,可以到附带的CD中查找可利用的完成好的项目。

 

Exercise 1: Identify Types as Value or Reference 练习1:识别值类型和引用类型。

In this exercise, you will write a console application that displays whether objects are value or reference types.

在这个练习中,你将编写一个控制台应用程序,用它来显示对象是值类型还是引用类型。

1.    Using Visual Studio, create a new console application project. Name the project List-Value-Types.

打开VS,建立一个新的控制台应用程序项目。名字为:List-Value-Types.

2.    Create instances of the following classes:

建立下列类的实例:

o        SByte

o        Byte

o        Int16

o        Int32

o        Int64

o        String

o        Exception

The following code demonstrates this:代码示例如下:

' VB
Dim a As SByte = 0
Dim b As Byte = 0
Dim c As Int16 = 0
Dim d As Int32 = 0
Dim e As Int64 = 0
Dim s As String = ""
Dim ex As Exception = New Exception
 
// C#
SByte a = 0;
Byte b =0;
Int
  
    
      16 c 
     = 0;
Int32 d = 0;
Int64 e = 0;
string s = "";
Exception ex = new Exception();

3.    Add each of the instances to a new object array, as the following code demonstrates:

将所有实例添加到一个新的Object类型数组types中。如下所示:

4.           ' VB
5.           Dim types As Object() = {a, b, c, d, e, s, ex}
6.            
7.           // C#
8.           object[] types = { a, b, c, d, e, s, ex };
9.            

10.Within a foreach loop, check the object.GetType().IsValueType property to determine whether the type is a value type. Display each type name and whether it is a value type or a reference type, as the following code demonstrates:

建一个foreach循环块,检查types数组中每个元素的GetType().IsValueType属性,来确定这个元素类型是否是值类型。显示数组中所有元素的类型名称。

11.       ' VB
12.       For Each o As Object In types
13.           Dim type As String
14.           If o.GetType.IsValueType Then
15.               type = "Value type"
16.           Else
17.               type = "Reference Type"
18.           End If
19.           Console.WriteLine("{0}: {1}", o.GetType, type)
20.       Next
21.        
22.       // C#
23.       foreach ( object o in types )
24.       {
25.           string type;
26.           if (o.GetType().IsValueType)
27.               type = "Value type";
28.           else
29.               type = "Reference Type";
30.        
31.           Console.WriteLine("{0}: {1}", o.GetType(), type);
32.       }

33.Run the console application, and verify that each type matches your understanding.

运行这个程序,检查每个类型是否与你的理解一致。

 

 

Exercise 2: Work with Strings and Arrays 练习2:使用字符串和数组

In this exercise, you will write a function to sort a string.

在这个练习中,你将实现一个存储字符串功能。

1.    Using Visual Studio, create a new console application project. Name the project SortString.

打开VS,建立一个新的控制台应用程序项目。名字为:SortString

2.    Define a string. Then use the String.Split method to separate the string into an array of words. The following code demonstrates this:

定义一个字符串。然后,使用String.Split方法来分割它,并将结果存入一个字符串数组。

3.           ' VB
4.           Dim s As String = "Microsoft .NET Framework 2.0 Application Development Foundation"
5.           Dim sa As String() = s.Split(" ")
6.            
7.           // C#
8.           string s = "Microsoft .NET Framework 2.0 Application Development Foundation";
9.           string[] sa = s.Split(' ');
10.        

11.Call the Array.Sort method to sort the array of words, as the following code demonstrates:

调用Array.Sort方法将字符串数组存入Array

12.       ' VB
13.       Array.Sort(sa)
14.        
15.       // C#
16.       Array.Sort(sa);

17.Call the String.Join method to convert the array of words back into a single string, and then write the string to the console. The following code sample demonstrates this:

调用String.Join方法来将这个字符串数组转换为一个字符串并输出。

18.       ' VB
19.       s = String.Join(" ", sa)
20.       Console.WriteLine(s)
21.        
22.       // C#
23.       s = string.Join(" ", sa);
24.       Console.WriteLine(s);

25.Run the console application, and verify that it works correctly.

运行并检查程序正确性。

 

 

Exercise 3: Work with Streams and Exceptions 练习3:使用流和异常

Consider a scenario in which a coworker wrote a simple Windows Forms application to view text files. However, users complain that it is very temperamental. If the user mistypes the filename or if the file is not available for any reason, the application fails with an unhandled exception error. You must add exception handling to the application to display friendly error messages to users if a file is not available.

考虑一个假设,程序员编写了一个简单的Windows 窗体应用程序用来显示文本文件。而用户抱怨这个程序非常不稳定。如果用户文件名称有问题或者其他什么原因导致的文件无效,这个应用程序因为一个未处理的异常错误而运行失败。如果文件无效,你要编写异常处理,用来给用户显示友好的错误信息。

1.    Copy the Chapter01\Lesson2-ViewFile folder from the companion CD to your hard disk, and open either the C# version or the Visual Basic .NET version of the ViewFile project.

从附带CD中拷贝Chapter01\Lesson2下的ViewFile目录到你的磁盘,打开C#VB项目中的任意一个ViewFile项目。

2.    Exceptions occur when users attempt to view a file. Therefore, edit the code that runs for the showButton.Click event. Add code to catch any type of exception that occurs, and display the error in a dialog box to the user. If an exception occurs after the TextReader object is initialized, you should close it whether or not an exception occurs. You will need two nested Try blocks: one to catch exceptions during the TextReader initialization, and a second one to catch exceptions when the file is read. The following code sample demonstrates this:

当用户想要浏览一个文件时发生了异常。因此,编辑代码中的showButton.Click事件。增加代码来捕获发现的任意类型的异常,并且显示给用户一个错误对话框。无论是否会有异常在TextReader对象初始化后发生,你都要关闭TextReader对象。你需要编写两个Try语句块,一个用来捕获TextReader初始化过程中的异常,另一个用来捕获文件读取时的异常。

3.           ' VB
4.           Try
5.               Dim tr As TextReader = New StreamReader(locationTextBox.Text)
6.               Try
7.                   displayTextBox.Text = tr.ReadToEnd
8.            
9.               Catch ex As Exception
10.               MessageBox.Show(ex.Message)
11.           Finally
12.               tr.Close()
13.           End Try
14.       Catch ex As Exception
15.           MessageBox.Show(ex.Message)
16.       End Try
17.        
18.       // C#
19.       try
20.       {
21.           TextReader tr = new StreamReader(locationTextBox.Text);
22.           try
23.           { displayTextBox.Text = tr.ReadToEnd(); }
24.           catch (Exception ex)
25.           { MessageBox.Show(ex.Message); }
26.           finally
27.           { tr.Close(); }
28.       }
29.       catch (Exception ex)
30.       { MessageBox.Show(ex.Message); }

31.Run your application. First verify that it can successfully display a text file. Then provide an invalid filename, and verify that a message box appears when an invalid filename is provided.

运行程序,首先检查它可以安全的显示一个文本文件。然后提供一个非法的文件名,并检查当这个非法文件名使用后弹出的信息提示。

32.Next add overloaded exception handling to catch System.IO.FileNotFoundException and System.UnauthorizedAccessException. The following code sample demonstrates this:

下面,重载异常处理来捕获System.IO.FileNotFoundException System.UnauthorizedAccessException.

33.       ' VB
34.       Try
35.           Dim tr As TextReader = New StreamReader(locationTextBox.Text)
36.           Try
37.               displayTextBox.Text = tr.ReadToEnd
38.           Catch ex As Exception
39.               MessageBox.Show(ex.Message)
40.           Finally
41.               tr.Close()
42.           End Try
43.       Catch ex As System.IO.FileNotFoundException
44.           MessageBox.Show("Sorry, the file does not exist.")
45.       Catch ex As System.UnauthorizedAccessException
46.           MessageBox.Show("Sorry, you lack sufficient privileges.")
47.       Catch ex As Exception
48.           MessageBox.Show(ex.Message)
49.       End Try
50.        
51.       // C#
52.       try
53.       {
54.           TextReader tr = new StreamReader(locationTextBox.Text);
55.           try
56.           { displayTextBox.Text = tr.ReadToEnd(); }
57.           catch (Exception ex)
58.           { MessageBox.Show(ex.Message); }
59.           finally
60.           { tr.Close(); }
61.       }
62.       catch (System.IO.FileNotFoundException ex)
63.       { MessageBox.Show("Sorry, the file does not exist."); }
64.       catch (System.UnauthorizedAccessException ex)
65.       { MessageBox.Show("Sorry, you lack sufficient privileges."); }
66.       catch (Exception ex)
67.       { MessageBox.Show(ex.Message); }

68.Run your application again, and verify that it provides your new error message if an invalid filename is provided.

 

 

Lesson Summary本课摘要

·         Reference types contain the address of data rather than the actual data.

·         引用类型实际包含的是真实数据的地址。

·         When you copy a value type, a second copy of the value is created. When you copy a reference type, only the pointer is copied. Therefore, if you copy a reference type and then modify the copy, both the copy and the original variables are changed.

·         当你复制一个值类型时,新建的是这个值的第二个拷贝。当你复制一个引用类型时,拷贝的只是一个指针。因此,假设你拷贝一个引用类型并修改这个拷贝,那么这个拷贝和原始数据的值都将被改变。

·         The .NET Framework includes a large number of built-in reference types that you can use directly or use to build your own custom types.

·         .net框架包含了大量的引用类型,你可以直接使用或者用他们来建立你自己的类型。

·         Strings are immutable; use the StringBuilder class to create a string dynamically.

·         字符串是不可变的;应该使用StringBuilder类来建立可变的字符串。

·         Use streams to read from and write to files, memory, and the network.

·         使用Stream来读写文件、内存和网络数据。

·         Use the Catch clause within Try blocks to filter exceptions by type. Close and dispose of nonmemory resources in the Finally clause of a Try block.

·         Try语句块中使用Catch子句来过滤不同类型的异常。在Try语句块中的Finally子句块中关闭和释放那些不需要内存的资源。

Lesson Review复习

You can use the following questions to test your knowledge of the information in Lesson 2, "Using Common Reference Types." The questions are also available on the companion CD if you prefer to review them in electronic form.

你可以通过下列问题来测试你在本课中学到的知识。

 

Answers 

Answers to these questions and explanations of why each answer choice is right or wrong are located in the "Answers" section at the end of the book.回答这些问题并对每一个正确或错误的答案进行说明。答案在本课结尾。

 

1. 

Which of the following are reference types? (Choose all that apply.)下面哪几个是引用类型。(多选)

A.    Types declared Nullable Nullable类型声明

B.    String

C.    Exception

D.    All types derived from System.Object 所有来源于System.object的类型。

2. 

What is the correct order for Catch clauses when handling different exception types?下面哪个是Catch子句处理捕获的异常时使用的顺序。

A.    Order from most general to most specific.从最全到最具体。

B.    Order from most likely to least likely to occur.从最相似到最不相似。

C.    Order from most specific to most general.从最具体到最全

D.    Order from least likely to most likely to occur.从最不相似到最相似。

3. 

When should you use the StringBuilder class instead of the String class?什么时候你需要使用StringBuilder类来代替String类。

A.    When building a string from shorter strings.将多个短字符串连成一个字符串时

B.    When working with text data longer than 256 bytes.当使用超过256bytes的文本数据时

C.    When you want to search and replace the contents of a string.当你要搜索并替换字符串内容时

D.    When a string is a value type.当一个字符串是值类型时。

4. 

Why should you close and dispose of resources in a Finally block instead of a Catch block?为什么你在Finally块中关闭并释放资源,而不用Catch语句块。

A.    It keeps you from having to repeat the operation in each Catch.你在每个Catch语句块中必须保持重复操作。

B.    Finally blocks run whether or not an exception occurs.Finally块无论是否发生异常都会执行。

C.    The compiler throws an error if resources are not disposed of in the Finally block.如果资源不是在Finally块中被释放,编译器将会抛出一个异常。

D.    You cannot dispose of resources in a Catch block.Catch语句块中,你无法释放所有资源。

Answers

1. 

Correct Answers: B and C

A.    Incorrect: Types declared as Nullable can only be value types.

错误:Nullable只能定义为值类型。

B.    Correct: Strings are reference types.正确

C.    Correct: Exceptions are reference types.正确

D.    Incorrect: Value types derive from System.Object, so not all derived types are reference types.

错误:值类型都来源于System.Object,但并不是所有来源的类型都是引用类型。

2. 

Correct Answer: C

A.    Incorrect: You should order Catch clauses from most specific to most general.

错误:正确顺序为最具体到最全面。

B.    Incorrect: The first type that matches is caught and subsequent Catch clauses are skipped.

错误:只有第一个匹配的异常会被捕获并处理,而后面的Catch将跳过,不会被执行。

C.    Correct: The first type that matches is caught, and subsequent Catch clauses are skipped. Therefore, you should order Catch clauses from most specific to most general to enable you to catch errors that you have specific error-handling for, while still catching other exceptions with the more general Catch clauses.

只有第一个匹配的异常会被捕获并处理,而后面的Catch将跳过,不会被执行。因此,只有将Catch的顺序从最具体到最全面来排列,才能使你通过指定错误处理来捕获错误,同时又可以使用更全面的Catch 子句来捕获其它的异常。

D.    Incorrect: The first type that matches is caught and subsequent Catch clauses are skipped.

只有第一个匹配的异常会被捕获并处理,而后面的Catch将跳过,不会被执行。

3. 

Correct Answer: A

A.    Correct: Using the String type to construct a dynamic string can result in a lot of temporary strings in memory because the String type is immutable. Therefore, using the StringBuilder class is preferable.使用String类型来构造可变字符串,会在内存中产生大量的临时字符串。因为String 类型内容是不可变的。因此,使用String builder类是更好的选择。

B.    Incorrect: Strings are limited to 32,767 bytes, not 256 bytes.错误:String 范围在32767bytes,不是256bytes

C.    Incorrect: You can search and replace with a standard String class.错误:你可以使用一个string类来搜索和替换

D.    Incorrect: Strings are never value types; they are reference types.错误Strings不是值类型,它们是引用类型。

4. 

Correct Answer: B

A.    Incorrect: While this statement is true, the real advantage of using a Finally block is that code is executed even if the runtime does not throw an exception. Code in a Catch block is executed only if an exception occurs.错误:这个描述是正确的,但是,真正有用的是Finally无论在何时都会被执行,而Catch只有在异常发生时才会被执行。

B.    Correct: Use Finally blocks for code that should run whether or not an exception occurs.正确:Finally无论在何时都会被执行。

C.    Incorrect: The compiler will not throw an error if you do not include a Finally block. Finally blocks are optional.错误:编译器不会抛出一个错误。Finally是可选的

D.    Incorrect: You can dispose of resources in a Catch block. However, the code will run only if an exception occurs. Typically, you need to dispose of resources whether or not an exception occurs.错误:你可以在Catch块中释放资源。可是这段代码只有在异常发生时才会被执行。特别是,无论是否发生异常,你都需要释放资源。

 

你可能感兴趣的:(application)