Thursday, November 08, 2007
I think it was Derek that first convinced me of the beauty of the Guid, and I have been using them in databases ever since.

Wade Wright has written up the "Gospel of the Guid". It has a humorous coverage of some of the good Guid reasons:

  • No database roundtrips to get the next integer ID
  • Easy merging, mirroring and deletion of erroneous merges
  • Ability to wire up relationships in memory before saving
I remember when I first started using Guids there was talk of them not being unique, due to dodgy network cards having the same MAC address. Thankfully that's no longer a problem.

Something that I struggle with though, is the lack of type safety when using Guids. e.g.

Guid personId = Guid.NewGuid();
Guid bookId = Guid.NewGuid();

Library.BorrowBook(personId, bookId);

...or is it this way around?

Library.BorrowBook(bookId, personId);

There's no compiler checking that the correct Guid is passed to the right parameter. I've been toying with a Guid wrapper that would be a bit like a typedef in C++, but typesafe. Has anyone already done this?
Saturday, December 15, 2007 5:15:34 PM (New Zealand Standard Time, UTC+12:00)
I think you're on the right lines of populating the row key *before* writing to the database, but giuds aren't very friendly somehow. Have you thought of using defined sequences for creating unique indexes? e.g. 'INVxxxxxx' for an invoice 'CSTxxxxxx' for a customer, 'PMTxxxxxx' for a payment? It becomes obvious which number applys to which object. Use the database to maintain and increment the numbers if you've got a highly transactional enviroment. There's no compiler check, but it can sure be unit tested :)
Tuesday, April 29, 2008 2:42:04 PM (New Zealand Standard Time, UTC+12:00)
Hi Kirk.
Last night I was Googling for a solution to a problem and found you blog.
I forgot about my problem and prototyped a quick solution for typed Guids.

My solution is sort of an anti-generic because whatever gets assigned to <T> is just a flag for type-safety instead of the contained type. This might be better described in a VB-like syntax as Guid(For T) as opposed to List(Of T).

This code will work as a single-file [C#] ConsoleApp. It could (should) be combined with a state class containing a 'static Dictionary<Guid, Type>' to prevent cross-breeding of Guid<T>s.

Provide implementations of CompareTo, Equals, etc. as required.

I'm off to try the LINQ to Spouse provider.

/*-- Get to the code already --*/
using System;
namespace TypedGuid
{
struct Guid<T>
{
private readonly Guid value;
public Guid Value
{
get { return value; }
}
public Guid(Guid value)
{
this.value = value;
}
public static Guid<T> NewGuid()
{
return new Guid<T>(Guid.NewGuid());
}
public override string ToString()
{
return value.ToString();
}
public static implicit operator Guid(Guid<T> typedId)
{
return typedId.Value;
}
}
class Program
{
static void Main(string[] args)
{
Guid untypedId = Guid.NewGuid();

Guid<Book> bookId = new Guid<Book>(untypedId);
Guid<Person> personId = Guid<Person>.NewGuid();

Library.BorrowBook(personId, bookId);

Console.In.ReadLine();
}
}
class Book
{
}
class Person
{
}
class Library
{
public static void BorrowBook(Guid<Person> personId, Guid<Book> bookId)
{
Console.Out.WriteLine(
"The person {0}",
Helper.Embrace(personId.ToString()));
Console.Out.WriteLine(
"has the book {0} on loan.",
Helper.Embrace(bookId.ToString()));
}
}
static
class Helper
{
public static string Embrace(string text)
{
return "{" + text + "}";
}
}
}

Tuesday, April 29, 2008 4:22:54 PM (New Zealand Standard Time, UTC+12:00)
Hi Simon,

Thanks for posting that sample code -- I like the way you've done it.

As you said in email, it's forcing compile errors. E.g.

/* Doesn't compile
Library.BorrowBook(bookId, personId);
*/
Library.BorrowBook(personId, bookId);

Sorry my blog doesn't highlight or indent properly!

Kirk
All comments require the approval of the site owner before being displayed.
Name
E-mail
Home page

Comment (HTML not allowed)