You will find there's large amount of code that passes about “Ids” of information rows they are mostly ints or guids. I possibly could get this to code safer by developing a different struct for that id of every database table. Then your type checker will assist you to find times when the incorrect ID is passed.

E.g the individual table includes a column calls PersonId and that we have code like:

DeletePerson(int personId)
DeleteCar(int carId)

Will it be easier to have:

struct PersonId
{
   private int id;
   // GetHashCode etc....
}

DeletePerson(PersionId persionId)
DeleteCar(CarId carId)
  • Has anybody got real existence experience of dong this?

  • Could it be well worth the overhead?

  • Or even more discomfort then its worth?

(It might also allow it to be simpler to alter the information enter in the database from the primary key, that's way I figured of the ideal to begin with)


You shouldn't say make use of an ORM another large change somewhere design when i know an ORM will be a more sensible choice, but that's not under my energy at the moment. However could make minor changes such as the above towards the module I'm focusing on at the moment.

Update: Note this isn't an internet application and also the Ids are stored in memory and passed about with WCF, so there's no conversion to/from strings in the edge. There's pointless the WCF interface can’t make use of the PersonId type etc. The PersonsId type etc can also be utilized in the WPF/Winforms UI code.

The only real naturally "untyped" little bit of the machine may be the database.


This appears to become lower towards the cost/advantage of investing time writing code the compiler can check better, or investing time writing more unit tests; I am decreasing more along the side of investing time on testing, as I must see a minimum of some unit tests within the code base.

It's difficult to determine how it may be worthwhile: I suggest doing the work only like a last measure and only when individuals are really mixing identifiers throughout development or confirming difficulty keeping them straight.

In web programs particularly it will not even provide the safety you are wishing for: typically you will be transforming strings into integers anyway. You will find way too many cases when you will find yourself writing silly code such as this:

int personId;
if (Int32.TryParse(Request["personId"], out personId)) { 
    this.person = this.PersonRepository.Get(new PersonId(personId));
}

Coping with complex condition in memory certainly enhances the situation for strongly-typed IDs, however i think Arthur's idea is better still: to prevent confusion, demand an entity instance rather than an identifier. In certain situations, performance and memory factors might make that not practical, but even individuals ought to be rare enough that code review could be just like effective with no gloomy-effects (quite the opposite!).

I have done something that did this, also it did not really provide any value. We did not have ambiguities such as the ones you are explaining, and when it comes to future-proofing, it managed to get slightly harder to implement additional features with no payback. (No ID's data type transformed in 2 years, anyway - it's could certainly happen sooner or later, but so far as I understand, the roi for your is presently negative.)

You can easily go for GUIDs, as if you recommended yourself. Then, you will not need to bother about passing an individual ID of "42" to DeleteCar() and accidentally remove the vehicle with ID of 42. GUIDs are unique should you pass an individual GUID to DeleteCar inside your code due to a programming typo, that GUID won't be a PK associated with a vehicle within the database.