Author Topic: .NET 2.0 Generics  (Read 4738 times)

0 Members and 1 Guest are viewing this topic.

Glenn R

  • Guest
.NET 2.0 Generics
« on: November 29, 2006, 06:47:18 PM »
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:
Code: [Select]
[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:
Code: [Select]
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:
Code: [Select]
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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: .NET 2.0 Generics
« Reply #1 on: November 29, 2006, 06:58:44 PM »
You expected no-one to catch this ... ?

Quote
catch (SerializationException sex)


excuse the pun    :-)
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

LE

  • Guest
Re: .NET 2.0 Generics
« Reply #2 on: November 29, 2006, 07:02:17 PM »
Quote
catch (SerializationException sex)

It is a sublime subliminal message hidden in there......
« Last Edit: November 29, 2006, 07:05:52 PM by LE »

Glenn R

  • Guest
Re: .NET 2.0 Generics
« Reply #3 on: November 29, 2006, 07:17:53 PM »
Caught by the one I knew would catch it first, hey Kerry ;)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: .NET 2.0 Generics
« Reply #4 on: November 29, 2006, 08:54:57 PM »
Just a couple of notes
Anyone putting this together will need the statement

using System.Collections.ObjectModel;

otherwise the Collection will not be recognised.

Serializing the object has some real potential, [once I can understand it :-) ]

Extra reading :
http://download.microsoft.com/download/c/b/f/cbfbdf30-de37-45a7-a806-20a93f94b7b8/Michaelis_ch11.pdf
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: .NET 2.0 Generics
« Reply #5 on: November 29, 2006, 09:04:26 PM »
From my original post Kerry:

This class is extending CollectionBase's .NET 2.0 generic counterpart, Collection<T> which is in System.Collections.ObjectModel.

Yeah binary serialization will take private as well as public, whereas XML serialization will only take public and it it's a collection class will only take the collection - nothing else.

Good fun eh Kerry? :D

Cheers,
Glenn.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: .NET 2.0 Generics
« Reply #6 on: November 29, 2006, 09:07:24 PM »
DUH !! I'm blind as well as Stupid .... sorry ..
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: .NET 2.0 Generics
« Reply #7 on: November 29, 2006, 09:14:17 PM »
Anyone testing may want to add something like

Console.ReadKey();

to the bottom of the DumpCars() method

so that the Command dialog stays open till a key is hit ...

///---- added
or something like this in Main ....
Code: [Select]
            if (cars != null)
                DumpCars(cars);
            Console.ReadKey();  // <-- kwb
            // Exercise an indexer...
            Car anotherCar = cars["G"];
            Console.WriteLine("Another car: {0}", anotherCar.Name);
            Console.ReadKey();  // <-- kwb
            //...and the other indexer...
            Car yetAnotherCar = cars[1];
            Console.WriteLine("Yet Another car: {0}", yetAnotherCar.Name);
            Console.ReadKey();  // <-- kwb
        }
///---------

Nice Stuff Glenn


hehehehe
is Sooty related to Brock ??
« Last Edit: November 29, 2006, 09:21:38 PM by Kerry Brown »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: .NET 2.0 Generics
« Reply #8 on: November 29, 2006, 09:31:59 PM »
Thanks Kerry. No Sooty isn't related to Brock - she's our dog's worst nightmare :) She actually got him to roll over the other night - honest  :-D
I usually add Console.Readline(); at the end but I must have left it off.

If you want to keep the console window open when the run is finished and you're not debugging:
Debug->Start Without Debugging or Ctrl+F5 will do the same.

I'm going to have to get around to retro-fitting a few classes that I use. The binary serialization is really appealing to me at the moment - also keeps prying little mitts out of the data file, instead of it being a free for all xml.

Draftek

  • Guest
Re: .NET 2.0 Generics
« Reply #9 on: December 13, 2006, 10:40:01 AM »
Thanks Glenn,

I just now had time to digest this. Very handy!

Now, I've got to go back and redesign my collection classes created the last few months....