C# Coding Standards – Prevent Developers from Using Constants

ccoding-standardscoding-styleteamwork

I have one one software system which allows developers to specify an ID or name to create NodeReferences. Both work fine, but ID's are not guaranteed to be the same across different environments. I've tried in documentation and in conversations to stress that ID's should not be hard coded (since they will break when deployed to a different environments), but some developers are still using them.

This works only in dev environment:

var level = LevelReference.ById(20);
var node = NodeReference.ByName(level, _patientGuid.ToString());

This works in all environments:

var app = ApplicationReference.ByName("Reporting");
var area = AreaReference.ByName(app, "Default");
var level = LevelReference.ByName(area, "Patient");
var node = NodeReference.ByName(level, _patientGuid.ToString());

I think the appeal is just that it produces fewer lines of code. The use of ID's is not by itself bad (since there are valid use cases like caching the ID returned from the server and using it later for faster look-up), but hard-coded ID's are bad. Most of the time the first code will throw an exception, but it's possible that it could be a valid ID for a different object than the developer intended, and this could result in very bad problems.

What's the best way to discourage the use of such constants in code? Ideally I'd like throw some kind of compiler error when I see code like the first example, or at least throw an exception before the call gets down to the database.

Best Answer

Hide the int ids in opaque objects/structs;

var id = level.id;

Here id is such a struct.

This way you can remove the ById(int) method and replace it with ById(Id) and it still lets you keep the cashed Ids for future use.

You can also create unique ID types for each reference type to ensure type safety (so you can't do NodeReference.ById(level.id)).