0

Please consider my use case: I'm developing a software system in which there are uniquely identified "items" of different types (users, documents, tickets etc.).

I've started the implementation, and while I'd like to move forward with the implementation, I'm not exactly sure what would be the most suitable unique identifier of the "items". It might be an auto-incremented integer, a GUID, a string containing a prefix + the creation time etc.

Obviously, variables of the unique identifier type are declared all over my classes, and if I intend to change it later - well, it can't be good...

My question is, is there a .NET mechanism for typedef-ing value types, so I can change the 'real' type and the type-specific functionality in a single location (for example, using extension methods) and not worry about the dozens of other occurrences in the code.

3
  • C# has no `typedef' equivalent, weak or strong. It's not entirely clear what you're trying to do --- if you can give a pseudocode example it might help to suggest alternatives. Commented Jan 24, 2015 at 17:32
  • Sounds like a problem that the Strategy Pattern was designed to solve for. Commented Jan 24, 2015 at 17:32
  • @Cory: sorry it's not clear. Consider lots of classes with the Id property of value type UniqueIdentifier, which is actually a GUID (for example). On each such class' constructor I'd add Id = UniqueIdentifier.Generate(); (probably an extension method). The class needs not know how Id is implemented or generated, and I can change UniqueIdentifier's implementation without changing the classes' code. Commented Jan 24, 2015 at 17:56

2 Answers 2

1

No, there isn't. Not globally. However you can make a base class, like:

 public class BaseEntity { public int Id { get; set; } } 

Then derive all of your objects from there:

 public class MyItem : BaseEntity { } 

Then you'd only change your type in one place.

You can create an alias for a type, but you need to define it on every module, can't be done globally:

 using MyIdType = System.Int32; 

Documentation for aliasing is here

That said: I don't think it's good practice to change these kind of things around... think twice, code once.

Sign up to request clarification or add additional context in comments.

6 Comments

he did say value types :)
@CoryNelson I thought he was referring to the value type that the identifier is, not the classes...
Correct, the value type refers to the unique identifier. I'm currently using aliasing but that's not the single-point solution I'm looking for. @Jcl, even if I think it all the way over and choose GUID (for example), it would still be 'cleaner' to define a UniqueIdentifier type and extend it rather than extending all GUIDs (or all strings!)
@ury I'm afraid there's no such solution in C#
@ury you can definitely define your own value type for an id, using a struct, but having a struct with just a Guid or int inside just for the sake of naming doesn't look right to me and smells from afar (if you are actually doing other things with that type, it might be a solution)
|
1

What about inheritance?

public class UniqueIdentifiedObject { public Guid Id { get; set; } } public class User : UniqueIdentifiedObject { // You don't need to stupidly repeat yourself (DRY) } 

If you can't use inheritance because you've already derived these classes from who know what other class... Then you can use generics:

public class User<TId> where TId : IEquatable<TId> { public TId Id { get; set; } } public class Employee<TId> where TId : IEquatable<TId> { public TId Id { get; set; } } 

This means that you'll need to provide the type of the whole unique identifier during your class instantiations:

Employee<Guid> employee = new Employee<Guid>(); 

I believe generics gets closer to what you're looking for, because it allows you to define a set of classes with an Id property but the class itself won't know what type of unique identifier is being used until some code instantiates the whole class. Obviously this has a big drawback: if you want to change the unique identifier type, you'll need to change all class instantiations...

Anyway, a massive find & replace using a regexp like (?:User|Employee|Boss|Document)<([A-Za-z0-9-_]+)> or something like this would be enough to change the type of unique identifier for every domain class in your project!).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.