Monday, 17 December 2012

c# for dummies: c sharp programming

c# for dummies: c sharp programming: THE SORTEDLIST CLASS As we mentioned in the Introduction section of this chapter, a SortedList is a data structure that stores key–valu...

c sharp programming


THE SORTEDLIST CLASS

As we mentioned in the Introduction section of this chapter, a SortedList is a
data structure that stores key–value pairs in sorted order based on the key.We
can use this data structure when it is important for the keys to be sorted, such
as in a standard word dictionary, where we expect the words in the dictionary
to be sorted alphabetically. Later in the chapter, we’ll also see how the class
can be used to store a list of single, sorted values.

Using the SortedList Class
We can use the SortedList class in much the same way we used the classes
in the previous sections, since the SortedList class is a specialization of the
DictionaryBase class.
To demonstrate this, the following code creates a SortedList object that
contains three names and IP addresses:
SortedList myips = New SortedList();
myips.Add("Mike", "192.155.12.1");
myips.Add("David", "192.155.12.2");
myips.Add("Bernica", "192.155.12.3");

The name is the key and the IP address is the stored value.

The generic version of the SortedList class allows you to decide the data
type of both the key and the value:
SortedList<Tkey, TValue>
For this example, we could instantiate myips like this:
SortedList<string, string> myips =
new SortedList<string, string>();

A grade book sorted list might be instantiated as follows:
SortedList<string, int> gradeBook =
new SortedList<string, int>();
We can retrieve the values by using the Item method with a key as the
argument:

Foreach(Object key In myips.Keys)
Console.WriteLine("Name:"&key+"\n" +
"IP: " & myips.Item(key))
This fragment produces the following output:


Alternatively, we can also access this list by referencing the index num-
bers where these values (and keys) are stored internally in the arrays, which
actually store the data. Here’s how:
for(inti=0;i< myips.Count; i++)
Console.WriteLine("Name:"+ myips.GetKey(i) + "\n" +
"IP: " & myips.GetByIndex(i));


This code fragment produces the exact same sorted list of names and IP
addresses:



A key–value pair can be removed from a SortedList by either specifying a
key or specifying an index number, as in the following code fragment, which
demonstrates both removal methods:
myips.Remove("David");
myips.RemoveAt(1);

If you want to use index-based access into a SortedList but don’t know the
indexes where a particular key or value is stored, you can use the following
methods to determine those values:
int indexDavid = myips.GetIndexOfKey("David");
int indexIPDavid = _
myips.GetIndexOfValue(myips.Item("David"));
The SortedList class contains many other methods and you are encouraged
to explore them via VS.NET’s online documentation.

c# for dummies: c sharp programming

c# for dummies: c sharp programming: THE GENERIC KEYVALUEPAIR CLASS C# provides a small class that allows you to create dictionary-like objects that store data based on a key. T...

c sharp programming

THE GENERIC KEYVALUEPAIR CLASS
C# provides a small class that allows you to create dictionary-like objects that
store data based on a key. This class is called the KeyValuePair class. Each
object can only hold one key and one value, so its use is limited.
A KeyValuePair object is instantiated like this:
KeyValuePair<string, int> mcmillan =
new KeyValuePair<string, int>("McMillan", 99);
The key and the value are retrieved individually:
Console.Write(mcmillan.Key);
Console.Write(""+ mcmillan.Value);


The KeyValuePair class is better used if you put the objects in an array. The
following program demonstrates how a simple grade book might be imple-
mented:

using System;
using System.Collections.Generic;
using System.Text;
namespace Generics
{
class Program
{
static void Main(string[] args)

{
KeyValuePair<string, int>[] gradeBook = new
KeyValuePair<string, int>[10];
gradeBook[0] = new KeyValuePair<string,
int>("McMillan", 99);
gradeBook[1] = new KeyValuePair<string,
int>("Ruff", 64);
for (inti=0;i<= gradeBook.GetUpperBound(0); i++)
if (gradeBook[i].Value != 0)
Console.WriteLine(gradeBook[i].Key + ": " +
gradeBook[i].Value);
Console.Read();
}
}

}

c# for dummies: c sharp programming

c# for dummies: c sharp programming: Other DictionaryBase Methods There are two other methods that are members of the DictionaryBase class: CopyTo and GetEnumerator. We dis...

c sharp programming


Other DictionaryBase Methods
There are two other methods that are members of the DictionaryBase class:
CopyTo and GetEnumerator. We discuss these methods in this section.
The CopyTo method copies the contents of a dictionary to a one-
dimensional array. The array should be declared as a DictionaryEntry array,
though you can declare it asObject and then use theCType function to convert
the objects to DictionaryEntry.
The following code fragment demonstrates howto use the CopyTomethod:
IPAddresses myIPs = new IPAddresses("c:\ips.txt");
DictionaryEntry[] ips = _
new DictionaryEntry[myIPs.Count-1];
myIPs.CopyTo(ips, 0);

The formula used to size the array takes the number of elements in the dic-
tionary and then subtracts one to account for a zero-based array. The CopyTo
method takes two arguments: the array to copy to and the index position to
start copying from. If you want to place the contents of a dictionary at the
end of an existing array, for example, you would specify the upper bound of
the array plus one as the second argument.
Once we get the data from the dictionary into an array, we want to work
with the contents of the array, or at least display the values. Here’s some code
to do that:
for(inti=0;i<= ips.GetUpperBound(0); i++)
Console.WriteLine(ips[i]);



Unfortunately, this is not what we want. The problem is that we’re storing
he data in the array as DictionaryEntry objects, and that’s exactly what we
see. If we use the ToString method:
Console.WriteLine(ips[ndex]ToString())
we get the same thing. In order to actually view the data in a DictionaryEntry
object,we have to use either the Key property or the Value property, depending
on if the object we’re querying holds key data or value data. So how do we
know which is which? When the contents of the dictionary are copied to the
array, the data is copied in key–value order. So the ?rst object is a key, the
second object is a value, the third object is a key, and so on.
Now we can write a code fragment that allows us to actually see the data:

for(inti=0;i<= ips.GetUpperBound(0); i++) {
Console.WriteLine(ips[index].Key);
Console.WriteLine(ips[index].Value);
}

c# for dummies: c sharp programming

c# for dummies: c sharp programming: Other DictionaryBase Methods There are two other methods that are members of the DictionaryBase class: CopyTo and GetEnumerator. We discuss ...

c sharp programming

Other DictionaryBase Methods
There are two other methods that are members of the DictionaryBase class:
CopyTo and GetEnumerator. We discuss these methods in this section.
The CopyTo method copies the contents of a dictionary to a one-
dimensional array. The array should be declared as a DictionaryEntry array,
though you can declare it asObject and then use theCType function to convert
the objects to DictionaryEntry.
The following code fragment demonstrates howto use the CopyTomethod:
IPAddresses myIPs = new IPAddresses("c:\ips.txt");
DictionaryEntry[] ips = _
new DictionaryEntry[myIPs.Count-1];
myIPs.CopyTo(ips, 0);

The formula used to size the array takes the number of elements in the dic-
tionary and then subtracts one to account for a zero-based array. The CopyTo
method takes two arguments: the array to copy to and the index position to
start copying from. If you want to place the contents of a dictionary at the
end of an existing array, for example, you would specify the upper bound of
the array plus one as the second argument.
Once we get the data from the dictionary into an array, we want to work
with the contents of the array, or at least display the values. Here’s some code
to do that:
for(inti=0;i<= ips.GetUpperBound(0); i++)
Console.WriteLine(ips[i]);



Unfortunately, this is not what we want. The problem is that we’re storing
he data in the array as DictionaryEntry objects, and that’s exactly what we
see. If we use the ToString method:
Console.WriteLine(ips[ndex]ToString())
we get the same thing. In order to actually view the data in a DictionaryEntry
object,we have to use either the Key property or the Value property, depending
on if the object we’re querying holds key data or value data. So how do we
know which is which? When the contents of the dictionary are copied to the
array, the data is copied in key–value order. So the ?rst object is a key, the
second object is a value, the third object is a key, and so on.
Now we can write a code fragment that allows us to actually see the data:

for(inti=0;i<= ips.GetUpperBound(0); i++) {
Console.WriteLine(ips[index].Key);
Console.WriteLine(ips[index].Value);
}

c# for dummies: c sharp programming

c# for dummies: c sharp programming: Fundamental DictionaryBase Class Methods and Properties When working with a dictionary object, there are several operations you want to...

c sharp programming


Fundamental DictionaryBase Class
Methods and Properties
When working with a dictionary object, there are several operations you want
to perform. At aminimum, you need an Addmethod to add new data, an Item
method to retrieve a value, a Remove method to remove a key–value pair, and
a Clear method to clear the data structure of all data.
Let’s begin the discussion of implementing a dictionary by looking at a
simple example class. The following code shows the implementation of a
class that stores names and IP addresses:


public class IPAddresses : DictionaryBase {
public IPAddresses() {
}
public void Add(string name, string ip) {
base.InnerHashtable.Add(name, ip);

}
public string Item(string name) {
return base.InnerHashtable[name].ToString();
}
public void Remove(string name) {
base.InnerHashtable.Remove(name);
}
}

As you can see, these methods were very easy to build. The ?rst method
implemented is the constructor. This is a simple method that does nothing
but call the default constructor for the base class. The Add method takes a
name/IP address pair as arguments and passes them to the Add method of the
InnerHashTable object, which is instantiated in the base class.
The Item method is used to retrieve a value given a speci?c key. The key is
passed to the corresponding Item method of the InnerHashTable object. The
value that is stored with the associated key in the inner hash table is returned.
Finally, the Remove method receives a key as an argument and passes
the argument to the associated Remove method of the inner hash table. The
method then removes both the key and its associated value from the hash
table.

There are two methods we can use without implementing them: Count
and Clear. The Count method returns the number of DictionaryEntry objects
stored in the inner hash table, whereas Clear removes all the DictionaryEntry
objects from the inner hash table.
Let’s look at a program that utilizes these methods:

class chapter9 {
static void Main() {
IPAddresses myIPs = new IPAddresses();
myIPs.Add("Mike", "192.155.12.1");
myIPs.Add("David", "192.155.12.2");
myIPs.Add("Bernica", "192.155.12.3");
Console.WriteLine("There are"+ myIPs.Count +
"IP addresses");
Console.WriteLine("David's ip address: " +
myIPs.Item("David"));
myIPs.Clear();

Console.WriteLine("There are"+ myIPs.Count +
"IP addresses");
}
}

The output from this program is in the image below


One modi?cation we might want to make to the class is to overload the
constructor so that we can load data into a dictionary from a ?le. Here’s the
code for the new constructor, which you can just add into the IPAddresses
class de?nition:
public IPAddresses(string txtFile) {
string line;
string[] words;
StreamReader inFile;
inFile = File.OpenText(txtFile);
while(inFile.Peek() != -1) {
line = inFile.ReadLine();
words = line.Split(',');
this.InnerHashtable.Add(words[0], words[1]);
}
inFile.Close();
}

Now here’s a new program to test the constructor:
class chapter9 {
static void Main() {
for(inti=0;i<4; i++)
Console.WriteLine();

IPAddresses myIPs = _
new IPAddresses("c:\\data\\ips.txt");
Console.WriteLine("There are {0} IP addresses",
myIPs.Count);
Console.WriteLine("David's IP address: " +
myIPs.Item("David"));
Console.WriteLine("Bernica's IP address: " +
myIPs.Item("Bernica"));
Console.WriteLine("Mike's IP address: " +
myIPs.Item("Mike"));
}
}


c# for dummies: c sharp programming

c# for dummies: c sharp programming: Building Dictionaries: The DictionaryBase Class and the SortedList Class A dictionary is a data structure that stores data as a key–value pa...

c sharp programming

Building Dictionaries:
The DictionaryBase Class
and the SortedList Class


A dictionary is a data structure that stores data as a key–value pair. The
DictionaryBase class is used as an abstract class to implement different data
structures that all store data as key–value pairs. These data structures can be
hash tables, linked lists, or some other data structure type. In this chapter,
we examine how to create basic dictionaries and how to use the inherited
methods of the DictionaryBase class.We will use these techniques later when
we explore more specialized data structures.
One example of a dictionary-based data structure is the SortedList. This
class stores key–value pairs in sorted order based on the key. It is an interesting
data structure because you can also access the values stored in the structure
by referring to the value’s index position in the data structure, which makes
the structure behave somewhat like an array.We examine the behavior of the
SortedList class at the end of the chapter.


THE DICTIONARYBASE CLASS
You can think of a dictionary data structure as a computerizedword dictionary.
The word you are looking up is the key, and the de?nition of the word is the
value. The DictionaryBase class is an abstract (MustInherit) class that is used
as a basis for specialized dictionary implementations.
The key–value pairs stored in a dictionary are actually stored as Dictio-
naryEntry objects. The DictionaryEntry structure provides two ?elds, one for
the key and one for the value. The only two properties (or methods) we’re
interested in with this structure are the Key and Value properties. Thesemeth-
ods return the values stored when a key–value pair is entered into a dictionary.

Internally, key–value pairs are stored in a hash table object called Inner-
HashTable.
just view it as an ef?cient data structure for storing key–value pairs.
The DictionaryBase class actually implements an interface from the Sys-
tem.Collections namespace, IDictionary. This interface is actually the basis
for many of the classes we’ll study later in this book, including the ListDic-
tionary class and the Hashtable class.


c# for dummies: c sharp programming

c# for dummies: c sharp programming: IStructuralEquatable and IStructuralComparable As we said in the previous chapter, structs implement structural comparison by de- fault: two...

c sharp programming

IStructuralEquatable and IStructuralComparable
As we said in the previous chapter, structs implement structural comparison by de-
fault: two structs are equal if all of their fields are equal. Sometimes, however, struc-
tural equality and order comparison are useful as plug-in options on other types as
well—such as arrays and tuples. Framework 4.0 introduces two new interfaces to
help with this:
public interface IStructuralEquatable
{
  bool Equals (object other, IEqualityComparer comparer);
  int GetHashCode (IEqualityComparer comparer);
}
public interface IStructuralComparable
{
  int CompareTo (object other, IComparer comparer);
}
The IEqualityComparer/IComparer  that you pass  in are applied  to each  individual
element in the composite object. We can demonstrate this using arrays and tuples,
which implement these interfaces: in the following example, we compare two arrays
for equality: first using the default Equals method, and then using IStructuralEquat
able’s version:
int[] a1 = { 1, 2, 3 };
int[] a2 = { 1, 2, 3 };
Console.Write (a1.Equals (a2));                                 // False
Console.Write (a1.Equals (a2, EqualityComparer<int>.Default));  // True

Here’s another example:
string[] a1 = "the quick brown fox".Split();
string[] a2 = "THE QUICK BROWN FOX".Split();
bool isTrue = a1.Equals (a2, StringComparer.InvariantCultureIgnoreCase);
Tuples work in the same way:
var t1 = Tuple.Create (1, "foo");
var t2 = Tuple.Create (1, "FOO");
bool isTrue = t1.Equals (t2, StringComparer.InvariantCultureIgnoreCase);
int zero = t1.CompareTo (t2, StringComparer.InvariantCultureIgnoreCase);
The difference with tuples, though, is that their default equality and order compar-
ison implementations also apply structural comparisons:
var t1 = Tuple.Create (1, "FOO");
var t2 = Tuple.Create (1, "FOO");
Console.WriteLine (t1.Equals (t2));   // True

c# for dummies: c sharp programming

c# for dummies: c sharp programming: IComparer and Comparer Comparers are used to switch in custom ordering logic for sorted dictionaries and collections. Note that a comparer i...

c sharp programming

IComparer and Comparer
Comparers are used to switch in custom ordering logic for sorted dictionaries and
collections.
Note that a comparer is useless to the unsorted dictionaries such as Dictionary and
Hashtable—these  require  an  IEqualityComparer  to  get  hash  codes.  Similarly,  an
equality comparer is useless for sorted dictionaries and collections.
Here are the IComparer interface definitions:
public interface IComparer
{
  int Compare(object x, object y);
}
public interface IComparer <in T>
{
  int Compare(T x, T y);
}
As with equality comparers,  there’s an abstract class you can  subtype  instead of
implementing the interfaces:
public abstract class Comparer<T> : IComparer, IComparer<T>
{
   public static Comparer<T> Default { get; }
   public abstract int Compare (T x, T y);       // Implemented by you
   int IComparer.Compare (object x, object y);   // Implemented for you
}
The following example illustrates a class that describes a wish, and a comparer that
sorts wishes by priority:

class Wish
{
  public string Name;
  public int Priority;
  public Wish (string name, int priority)
  {
    Name = name;
    Priority = priority;
  }
}
class PriorityComparer : Comparer <Wish>
{
  public override int Compare (Wish x, Wish y)
  {
    if (object.Equals (x, y)) return 0;          // Fail-safe check
    return x.Priority.CompareTo (y.Priority);
  }
}

The object.Equals check ensures that we can never contradict the Equals method.
Calling the static object.Equals method in this case is better than calling x.Equals
because it still works if x is null!
Here’s how our PriorityComparer is used to sort a List:
var wishList = new List<Wish>();
wishList.Add (new Wish ("Peace", 2));
wishList.Add (new Wish ("Wealth", 3));
wishList.Add (new Wish ("Love", 2));
wishList.Add (new Wish ("3 more wishes", 1));
wishList.Sort (new PriorityComparer());
foreach (Wish w in wishList) Console.Write (w.Name + " | ");
// OUTPUT: 3 more wishes | Love | Peace | Wealth |
In the next example, SurnameComparer allows you to sort surname strings in an order
suitable for a phonebook listing:
class SurnameComparer : Comparer <string>
{
  string Normalize (string s)
  {
    s = s.Trim().ToUpper();
    if (s.StartsWith ("MC")) s = "MAC" + s.Substring (2);
    return s;
  }

  public override int Compare (string x, string y)
  {
    return Normalize (x).CompareTo (Normalize (y));
  }
}
Here’s SurnameComparer in use in a sorted dictionary:
var dic = new SortedDictionary<string,string> (new SurnameComparer());
dic.Add ("MacPhail", "second!");
dic.Add ("MacWilliam", "third!");
dic.Add ("McDonald", "first!");
foreach (string s in dic.Values)
  Console.Write (s + " ");              // first! second! third!

c# for dummies: c sharp programming

c# for dummies: c sharp programming: Plugging in Equality and Order A type’s default equating or comparison implementation typically reflects what is most “natural” for that typ...

c sharp programming

Plugging in Equality and Order


A type’s default equating or comparison implementation typically reflects what is
most “natural” for that type. Sometimes, however, the default behavior is not what
you want.  You might  need  a  dictionary whose  string-type  key  is  treated  case-
insensitively. Or you might want a sorted list of customers, sorted by each customer’s
postcode. For this reason, the .NET Framework also defines a matching set of “plug-
in” protocols. The plug-in protocols achieve two things:

• They allow you to switch in alternative equating or comparison behavior.
• They allow you to use a dictionary or sorted collection with a key type that’s
not intrinsically equatable or comparable.

The plug-in protocols consist of the following interfaces:
IEqualityComparer and IEqualityComparer<T>
• Performs plug-in equality comparison and hashing
• Recognized by Hashtable and Dictionary
IComparer and IComparer<T>
• Performs plug-in order comparison
• Recognized by the sorted dictionaries and collections; also, Array.Sort
Each interface comes in generic and nongeneric forms. The IEqualityComparer in-
terfaces also have a default implementation in a class called EqualityComparer.
In addition, Framework 4.0 adds two new interfaces called IStructuralEquatable
and IStructuralComparable, which allow the option of structural comparisons on
classes and arrays.


IEqualityComparer and EqualityComparer
An equality comparer switches  in nondefault equality and hashing behavior, pri-
marily for the Dictionary and Hashtable classes.

Recall  the requirements of a hashtable-based dictionary.  It needs answers  to  two
questions for any given key:
• Is it the same as another?
• What is its integer hash code?
An  equality  comparer  answers  these  questions  by  implementing  the
IEqualityComparer interfaces:
public interface IEqualityComparer<T>
{
   bool Equals (T x, T y);
   int GetHashCode (T obj);
}
public interface IEqualityComparer     // Nongeneric version
{
   bool Equals (object x, object y);
   int GetHashCode (object obj);
}
To write a custom comparer, you implement one or both of these interfaces (im-
plementing both gives maximum interoperability). As this is somewhat tedious, an
alternative is to subclass the abstract EqualityComparer class, defined as follows:

public abstract class EqualityComparer<T> : IEqualityComparer,
                                            IEqualityComparer<T>
{
  public abstract bool Equals (T x, T y);
  public abstract int GetHashCode (T obj);
  bool IEqualityComparer.Equals (object x, object y);
  int IEqualityComparer.GetHashCode (object obj);
  public static EqualityComparer<T> Default { get; }
}
EqualityComparer implements both interfaces; your job is simply to override the two
abstract methods.

The semantics for Equals and GetHashCode follow the same rules for object.Equals
and object.GetHashCode, In the following example, we define
a Customer class with two fields, and then write an equality comparer that matches
both the first and last names:
public class Customer
{
  public string LastName;
  public string FirstName;
  public Customer (string last, string first)
  {
    LastName = last;
    FirstName = first;
  }
}

public class LastFirstEqComparer : EqualityComparer <Customer>
{
  public override bool Equals (Customer x, Customer y)
  {
    return x.LastName == y.LastName && x.FirstName == y.FirstName;
  }
  public override int GetHashCode (Customer obj)
  {
    return (obj.LastName + ";" + obj.FirstName).GetHashCode();
  }
}
To illustrate how this works, we’ll create two customers:
Customer c1 = new Customer ("Bloggs", "Joe");
Customer c2 = new Customer ("Bloggs", "Joe");
Because we haven’t overridden object.Equals, normal reference  type equality se-
mantics apply:
Console.WriteLine (c1 == c2);               // False
Console.WriteLine (c1.Equals (c2));         // False
The  same  default  equality  semantics  apply  when  using  these  customers  in  a
Dictionary without specifying an equality comparer:
var d = new Dictionary<Customer, string>();
d [c1] = "Joe";
Console.WriteLine (d.ContainsKey (c2));         // False

Now with the custom equality comparer:
var eqComparer = new LastFirstEqComparer();
var d = new Dictionary<Customer, string> (eqComparer);
d [c1] = "Joe";
Console.WriteLine (d.ContainsKey (c2));         // True
In  this  example,  we  would  have  to  be  careful  not  to  change  the  customer’s
FirstName or LastName while it was in use in the dictionary. Otherwise, its hash code
would change and the Dictionary would break.


EqualityComparer<T>.Default
Calling EqualityComparer<T>.Default returns a general-purpose equality comparer
that can be used as an alternative to the static object.Equals method. The advantage
is that first checks if T implements IEquatable<T> and if so, calls that implementation
instead, avoiding the boxing overhead. This is particularly useful in generic methods:
static bool Foo<T> (T x, T y)
 {
   bool same = EqualityComparer<T>.Default.Equals (x, y);
  ...

c# for dummies: c sharp programming

c# for dummies: c sharp programming: ReadOnlyCollection ReadOnlyCollection is a wrapper, or proxy, that provides a read-only view of a collection. This is useful in allowi...

c sharp programming

ReadOnlyCollection<T>

ReadOnlyCollection<T> is a wrapper, or proxy, that provides a read-only view of a
collection. This is useful in allowing a class to publicly expose read-only access to a
collection that the class can still update internally.
A read-only collection accepts  the  input collection  in  its constructor,  to which  it
maintains a permanent reference. It doesn’t take a static copy of the input collection,
so  subsequent  changes  to  the  input  collection  are  visible  through  the  read-only
wrapper.
To illustrate, suppose your class wants to provide read-only public access to a list
of strings called Names:
public class Test
{
  public List<string> Names { get; private set; }
}

This only does half the job. Although other types cannot reassign the Names property,
they can still call Add, Remove, or Clear on the list. The ReadOnlyCollection<T> class
resolves this:
public class Test
{
  List<string> names;
  public ReadOnlyCollection<string> Names { get; private set; }
  public Test()
  {
    names = new List<string>();
    Names = new ReadOnlyCollection<string> (names);
  }
  public void AddInternally() { names.Add ("test"); }
}
Now, only members within the Test class can alter the list of names:
Test t = new Test();
Console.WriteLine (t.Names.Count);       // 0
t.AddInternally();
Console.WriteLine (t.Names.Count);       // 1

t.Names.Add ("test");                    // Compiler error
((IList<string>) t.Names).Add ("test");  // NotSupportedException