I had some time and wanted to deepen my understanding of some .NET topics, so I decided to look at generics. After reading up on these a bit more, you just gotta love them. In .NET 1.X, if you wanted to create a collection class, most people, including myself, derived a new class from the abstract base class CollectionBase.
This internally implements an ArrayList as a protected member, so your derived class could access it, but object users could not; however, I digress.
You then had to provide implementations for a dozen or so methods. Doesn't sound too bad....untill you need to contain some other type of object...stir well and repeat....and repeat. Gets very tedious after a while.
Along comes Generics and all this goes out the door. Here's an example:
[Serializable]
public class Cars : Collection<Car>
{
Car _currentCar;
public Car CurrentCar
{
get { return _currentCar; }
set { _currentCar = value; }
}
public Car this[string name]
{
get
{
foreach (Car c in Items)
if (c.Name == name)
return c;
return null;
}
set
{
foreach (Car c in this)
if (c.Name == name)
{
this.Items[this.Items.IndexOf(c)] = value;
return;
}
}
}
}
[Serializable]
public class Car
{
/* Needed for xml serialization, but not for binary
private Car( ) { }
*/
public Car(string name, int currentSpeed)
{
this.name = name;
this.currentSpeed = currentSpeed;
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
private int currentSpeed;
public int CurrentSpeed
{
get { return currentSpeed; }
set { currentSpeed = value; }
}
}
First, we have a collection class that contains cars for want of a better example. You can see that is has a public property to return the current car and a custom indexer that uses a string as the key (the car's name). If you didn't want to maintain what the 'current' car is or be able to index via a string, then you could reduce the class to just this:
public class Cars : Collection<Car> { }
This class is extending CollectionBase's .NET 2.0 generic counterpart, Collection<T> which is in System.Collections.ObjectModel.
As a futher example, say you wanted to serialize and deserialize to binary, a collection of cars.
You would do so thusly:
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Ser
{
public class Test
{
static void Main( )
{
Cars cars = new Cars();
// Get my car...
Car gCar = new Car("G", 110);
cars.Add(gCar);
//...and wifey's...
Car jCar = new Car("J", 90);
cars.Add(jCar);
// Let the cat loose...
Car sootysCar = new Car("Sooty", 150);
cars.Add(sootysCar);
// Give the doggy a go as well...
Car maxsCar = new Car("Max", 130);
cars.Add(maxsCar);
// Set the current car...
cars.CurrentCar = sootysCar;
// Save the cars out...
Serialize(cars);
// Wipe 'em out
cars = null;
// Read 'em back in...
cars = Deserialize();
// Display some interesting stats about the cars...
if (cars != null)
DumpCars(cars);
// Exercise an indexer...
Car anotherCar = cars["G"];
Console.WriteLine("Another car: {0}", anotherCar.Name);
//...and the other indexer...
Car yetAnotherCar = cars[1];
Console.WriteLine("Yet Another car: {0}", yetAnotherCar.Name);
}
private static void DumpCars(Cars cars)
{
foreach (Car c in cars)
Console.WriteLine("{0}'s car is travelling at {1}kph...", c.Name, c.CurrentSpeed);
Console.WriteLine("Current car, {0}, is travelling at {1}kph...",
cars.CurrentCar.Name, cars.CurrentCar.CurrentSpeed);
}
static void Serialize(Cars cars)
{
FileStream fs = new FileStream("CarsDataFile.dat", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
try
{
bf.Serialize(fs, cars);
}
catch (SerializationException sex)
{
Console.WriteLine("Serialization failed: {0}", sex.Message);
throw;
}
finally
{
fs.Close();
}
}
static Cars Deserialize( )
{
Cars reconstitutedCars = null;
FileStream fs = new FileStream("CarsDataFile.dat", FileMode.Open);
try
{
BinaryFormatter bf = new BinaryFormatter();
reconstitutedCars = (Cars)bf.Deserialize(fs);
return reconstitutedCars;
}
catch (SerializationException sex)
{
Console.WriteLine("Deserialization failed: {0}", sex.Message);
throw;
}
finally
{
fs.Close();
}
}
}
}
Comments anyone?
Cheers,
Glenn.