There are numerous times you have an interface that accepts similar type arguments that have a separate domain logic meaning:
public static class Database
{
public static bool HasAccess(string userId, string documentId) { return true; }
}
Now it's quite easy to have someone key documentId instead of userId and vice versa. One could prevent that by abstracting the data type of the arguments:
public class UserId
{
public string Value { get; internal set; }
public static implicit operator string(UserId id) { return id.Value; }
}
public class DocumentId
{
public string Value { get; internal set; }
public static implicit operator string(DocumentId id) { return id.Value; }
}
public static class Database
{
public static bool HasAccess(UserId userId, DocumentId documentId) { return true; }
}
This way you get a nice compiler warning if you type in arguments out of order:
UserId e = new UserId() { Value = "a" };
DocumentId d = new DocumentId() { Value = "b" };
Database.HasAccess(d, e);
You also get the ability to change abstracted type in without affecting the rest of the system but that's not very likely. Would abstracting type be a good idea to get more type safety?
The question relates to C# solutions but short descriptions in other languages is welcome.
EDIT: Removed the implicit cast from string and pointing finger at the C# tag.