Tải bản đầy đủ (.pdf) (6 trang)

Enabling Section ppt

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (30.99 KB, 6 trang )



Enabling Notifications with Events
In the previous section, you saw how to declare a delegate type, call a delegate, and
create delegate instances. However, this is only half the story. Although delegates allow
you to invoke any number of methods indirectly, you still have to invoke the delegate
explicitly. In many cases, it would be useful to have the delegate run automatically when
something significant happens. For example, in the automated factory scenario, it could
be vital to be able to invoke the stopMachinery delegate and halt the equipment if a
machine overheats. In the .NET Framework, events allow you to define and trap
significant actions, and arrange for a delegate to be called to handle the situation. Many
classes in the .NET Framework expose events. Most of the controls that you can place on
a Windows form, and the Windows Form class itself, use events to allow you to run code
when, for example, the user clicks a button or types something in to a field. You can also
define your own events.


1. Locate the IDisposable.Dispose method. Comment out the throw new Exception
statement. The enumerator does not use any resources that require explicit
disposal, so this method does not need to do anything. It must still be present,
however. For more information about the Dispose method, refer to Chapter 13.
2. Build the solution and fix any errors that are reported.
Initializing a Variable Defined with a Type Parameter
You should have noticed that the statement that defines and initializes the currentItem
variable uses the default keyword. This keyword is a new feature in C# 2.0.
The currentItem variable is defined by using the type parameter T. When the program is
written and compiled, the actual type that will be substituted for T might not be known—
this issue is only resolved when the code is executed. This makes it difficult to specify
how the variable should be initialized. The temptation would be to set it to null. However,
if the type substituted for T is a value type, then this is an illegal assignment (you cannot
set value types to null, only reference types). Similarly, if you set it to 0 in the


expectation that the type will be numeric, then this will be illegal if the type used is
actually a reference type. There are other possibilities as well—T could be a boolean for
example. The default keyword solves this problem. The value used to initialize the
variable will be determined when the statement is executed; if T is a reference type
default(T) returns null, if T is numeric, default(T) returns 0, and if T is a boolean,
default(T) returns false. If T is a struct, the individual fields in the struct are initialized in
the same way (reference fields are set to null, numeric fields are set to 0, and boolean
fields are set to false.)
Implementing the IEnumerable Interface
In the following exercise, you will modify the binary tree class to implement the
IEnumerable interface. The GetEnumerator method will return a TreeEnumerator<T>
object.
Implement the IEnumerable<T> interface in the Tree<T> class
1. In the Solution Explorer, double click the file Tree.cs to display the Tree<T> class
in the Code and Text Editor window.
2. Modify the definition of the Tree<T> class so that it implements the
IEnumerable<T> interface, as shown below:
public class Tree<T> : IEnumerable<T> where T : IComparable<T>
Notice that constraints are always placed at the end of the class definition.
3. Right-click the IEnumerable<T> interface in the class definition, point to
Implement Interface, and then click Implement Interface Explicitly.
This action generates implementations of the IEnumerable<T>.GetEnumerator and
the IEnumerable.GetEnumerator methods and adds them to the close. The
IEnumerable interface method is implemented because the IEnumerable<T>
interface inherits from IEnumerable.
4. Locate the IEnumerable<T>.GetEnumerator method near the end of the class.
Modify the body of the GetEnumerator() method, replacing the existing throw
statement as follows:
5. IEnumerator<T> IEnumerable<T>.GetEnumerator()
6. {

7. return new TreeEnumerator<T>(this);
}
The purpose of the GetEnumerator method is to construct an enumerator object for
iterating through the collection. In this case, all we need to do is build a new
TreeEnumerator<T> object by using the data in the tree.
8. Build the solution.
The project should compile cleanly, so correct any errors that are reported and
rebuild the solution if necessary.
You will now test the modified Tree<T> class by using a foreach statement to display the
contents of a binary tree.
Test the enumerator
1. On the File menu, point to Add and then click New Project. Add a new project by
using the Console Application template. Name the project EnumeratorTest and set
the Location to \Microsoft Press\Visual CSharp StepBy Step\Chapter
18\BinaryTree, and then click OK.
2. Right-click the EnumeratorTest project in the Solution Explorer, and then click Set
as Startup Project.
3. On the Project menu, click Add Reference. In the Add Reference dialog box, click
the Projects tab. Click the BinaryTree project and then click OK.
The BinaryTree assembly will appear in the list of references for the
EnumeratorTest project in the Solution Explorer.
4. In the Code and Text Editor window displaying the Program class, add the
following using directive to the list at the top of the file:
using BinaryTree;
5. Add the following statements that create and populate a binary tree of integers to
the Main method:
6. Tree<int> tree1 = new Tree<int>(10);
7. tree1.Insert(5);
8. tree1.Insert(11);
9. tree1.Insert(5);

10. tree1.Insert(-12);
11. tree1.Insert(15);
12. tree1.Insert(0);
13. tree1.Insert(14);
14. tree1.Insert(-8);
tree1.Insert(10);
15. Add a foreach statement that enumerates the contents of the tree and displays the
results:
16. foreach (int data in tree1)
Console.WriteLine(data);
17. Build the solution, correcting any errors if necessary.
18. On the Debug menu, click Start Without Debugging.
When the program runs, the values should be displayed in the following sequence:
–12, –8, 0, 5, 5, 10, 10, 11, 14, 15
Press Enter to return to Visual Studio 2005.



1. Write(token, Color.Black);
2. }
3.
4. void ITokenVisitor.VisitIdentifier(string token)
5. {
6. Write(token, Color.Black);
7. }
8.
9. void ITokenVisitor.VisitKeyword(string token)
10. {
11. Write(token, Color.Blue);
12. }

13.
14. void ITokenVisitor.VisitOperator(string token)
15. {
16. Write(token, Color.Black);
17. }
18.
19. void ITokenVisitor.VisitPunctuator(string token)
20. {
21. Write(token, Color.Black);
22. }
23.
24. void ITokenVisitor.VisitStringLiteral(string token)
25. {
26. Write(token, Color.Green);
27. }
28.
29. void ITokenVisitor.VisitWhitespace(string token)
30. {
31. Write(token, Color.Black);
}
TIP
You can either type these methods into the Code and Text Editor window directly,
or you can use a feature of Visual Studio 2005 to add default implementations for
each one and then modify the method bodies with the appropriate code. To do this,
right-click the ITokenVisitor identifier in the class definition: sealed class
ColorSyntaxVisitor : ITokenVisitor In the context menu that appears, point to
Implement Interface and then click the Implement Interface Explicitly option.
Each method will contain a statement that throws an Exception with the message
“This method or operation is not implemented.” Replace this code with that shown
above.

32. On the Build menu, click Build Solution. Correct any errors, and then rebuild if
necessary.
33. On the Debug menu, click Start Without Debugging.
The Color Syntax form appears.
34. On the form, click Open.
The dummy code is displayed in the rich text box, with keywords in blue and
string literals in green.

35. Close the form to return to Visual Studio 2005.
Generating a Class Diagram
The Class View window is useful for displaying the hierarchy of classes and interfaces in
a project. Visual Studio 2005 also enables you to generate class diagrams which depict
this same information graphically (you can also use a class diagram to add new classes
and interfaces, and define methods, properties, and other class members).
To generate a new class diagram, click the Project menu, and then click Add New Item.
In the Add New Item window select the Class Diagram template and then click Add. This
action will generate an empty diagram, and you can create new types by dragging items
from the Class Designer category in the Toolbox. You can generate a diagram of all
existing classes by clicking and dragging them individually from the Class View window,
or by clicking and dragging the namespace to which they belong. The diagram shows the
relationships between the classes and interfaces, and you can expand the definition of
each class to show its contents. You can drag the classes and interfaces around to make
the diagram more readable, as shown in the following image:





Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×