Collection<T>
type, looks:
public class Branch {
public Branch() {
_branchNames = new BranchNamesCollection(this);
}
private BranchNamesCollection _branchNames;
public Collection<string> BranchNames {
get {
return _branchNames;
}
}
//---event raised when an item is removed---
public event EventHandler ItemRemoved;
//---called from within the BranchNamesCollection class---
protected virtual void RaiseItemRemovedEvent(EventArgs e) {
if (ItemRemoved != null) {
ItemRemoved(this, e);
}
}
private class BranchNamesCollection : Collection<string> {
private Branch _b;
public BranchNamesCollection(Branch b) _b = b;
//---fired when an item is removed---
protected override void RemoveItem(int index) {
base.RemoveItem(index);
_b.RaiseItemRemovedEvent(EventArgs.Empty);
}
}
}
There is now a class named BranchNamesCollection
within the Branch
class. The BranchNamesCollection
class is of type Collection<string>
. It overrides the RemoveItem()
method present in the Collection<T>
class. When an item is deleted from the collection, it proceeds to remove the item by calling the base RemoveItem()
method and then invoking a function defined in the Branch
class: RaiseItemRemovedEvent()
. The RaiseItemRemovedEvent()
function then raises the ItemRemoved event to notify the client that an item has been removed.
To service the ItemRemoved
event in the Branch
class, modify the code as follows:
static void Main(string[] args) {
Branch b = new Branch();
b.BranchNames.Add('ABC');
b.BranchNames.Add('XYZ');
b.BranchNames.Remove('XYZ');
foreach (string branchName in b.BranchNames) {
Console.WriteLine(branchName);
}
Console.ReadLine();
}
And here's the code's output:
Item removed!
As a rule of thumb, use the generic Collection<T>
class (because it is more extensible) as a return type from a public method, and use the generic List<T>
class for internal implementation.
Summary
Generics allow you define type-safe data structures without binding to specific fixed data types at design time. The end result is that your code becomes safer without sacrificing performance. In addition to showing you how to define your own generic class, this chapter also examined some of the generic classes provided in the .NET Framework class library, such as the generic LinkedList<T>
and Collection<T>
classes.
Chapter 10
Threading
Today's computer runs at more than 2GHz, a blazing speed improvement over just a few years ago. Almost all operating systems today are multitasking, meaning you can run more than one application at the same time. However, if your application is still executing code sequentially, you are not really utilizing the speed advancements of your latest processor. How many times have you seen an unresponsive application come back to life after it has completed a background task such as performing some mathematical calculations or network transfer? To fully utilize the extensive processing power of your computer and write responsive applications, understanding and using threads is important.
A thread is a sequential flow of execution within a program. A program can consist of multiple threads of execution, each capable of independent execution.
This chapter explains how to write multithreaded applications using the Thread class in the .NET Framework. It shows you how to:
□ Create a new thread of execution and stop it
□ Synchronize different threads using the various thread classes available
□ Write thread-safe Windows applications
□ Use the BackgroundWorker
component in Windows Forms to program background tasks.
The Need for Multithreading