1

I'm building an app in C# that needs a fixed-length id, which is a string representation of a hex number. E.g. "0fa5" is an example of such an id of length 4. The length would not need to change within the program at runtime, but may be changed in the future or for example in tests.

My question is about how to approach designing such a class. I've come up with two methods so far:

The first would be making a single class, IdType that has a static method SetExpectedLength(int) that should only be called once, otherwise it gives an exception:

class IdType 
{
    public static int ExpectedLength {get; private set;} = 0;
    public string Id {get; private set;} = "";

    public IdType(string id)
    {
        if (IdType.ExpectedLength== 0)
            throw new Exception("SetExpectedLength needs to be called first");

        if (id.Length != IdType.ExpectedLength)
            throw new Exception("Length constraints not satisfied!");

        this.Id = id;
    }

    public static void SetExpectedLength(int length)
    {
        if (IdType.Length == 0)
            IdType.ExpectedLength = length;
        else throw new Exception("SetExpectedLength can only be called once");
    }

    // other operations here...
}

The other approach would be making a base abstract class and deriving IdTypes of different lengths from it:

abstract class IdType 
{
    public string Id {get; protected set;}
}

// IdType of length 4
class IdType4 : IdType
{
    public readonly int Length = 4;

    public IdType4(string id)
    {
        if (id.Length != this.Length)
            throw new Exception("Length constraints not satisfied!");

        this.Id = id;
    }
}

The second approach seems more clean, however if I need a new length for the ids I would have to make a new class AND replace the instance of the old class everywhere it is used.

What is the best practice in this case? Is there another design pattern that I can use?

8
  • 4
    At first glance this sounds like a potential XY problem. Why do you need this four-digit hex-number-as-string id? What is the id used for? Distinguishing runtime instances of the program from some other program? Distinguishing between instances of this class at runtime? And why not simply use a constructor to ensure the object gets a valid length and/or id at construction time?
    – Ixrec
    Aug 8, 2015 at 10:49
  • 1
    I want to use the id for, say, peers in a network. It needs to be: a number and of fixed length (all ids must be the same length). C# does not natively support arbitrary-length integers, so I thought about making my own. Aug 8, 2015 at 10:51
  • 2
    On the second you don't even implement the abstract class.
    – paparazzo
    Aug 9, 2015 at 11:23
  • 1
    Have you looked at other, existing implementations of universally unique identifiers? If so, why aren't they useful for you? If not, perhaps it's the solution to your problem.
    – Thomas Owens
    Aug 9, 2015 at 17:18
  • 1
    1. System.Numerics.BigInteger Aug 9, 2015 at 21:10

3 Answers 3

1

The second approach seems more clean, however if I need a new length for the ids I would have to make a new class AND replace the instance of the old class everywhere it is used

You already gave the two striking arguments why this is exact the opposite of beeing clean. So you should avoid specific derivations for specific lengths. However, you wrote

length would not need to change within the program at runtime

so why don't you just make the current length a constant and set it to 4 at one single place in your code? When you later need different lengths, that will be the only place you will have to change, and the need for a method like SetExpectedLength will be removed. If you need to change the expected length once at the program start, then your solution 1 is fine.

The question you have to answer for yourself is if you just expect a future scenario where you have to replace 4 by, for example 5, for all IDs in your program, or a scenario where you have both kind of IDs to deal with simultanously. If the latter is the case, you should rely on having the passed string the correct length 4 or 5

1
  • This seems like a reasonable solution. If I need only one type of Id in the whole solution, I can just change it in the class, no need to set it externally. Thank you for the hints. Aug 10, 2015 at 9:31
1

Your code is much too complicated for such a simple requirement. This is because you are focusing on the representation (four hex characters) when you should be focusing on the thing represented, which is merely a two-byte integer. A C# ushort is precisely that type.

For convenience, you could create a struct (not a class) that contains a short and methods to convert to/from a four-byte hex string.

If you need arbitrary precision, then use System.Numerics.BigInteger instead. BigInteger already has methods to convert to and from strings.

2
  • What's wrong with a string? Aug 10, 2015 at 1:16
  • For such a simple use case I would agree. However, the four hex char example was given only for demonstration purposes. My intended ids would need to be much bigger than that. Although, you have given me a possible idea with using a fixed-size byte array... Aug 10, 2015 at 9:17
-3

I'm building an app in C# that needs a fixed-length id, which is a string representation of a hex number.

So use a string. Anything else is a waste of time.

On the day you find that you somehow passed an ID code string of the wrong length, add an extension method to check the string length.

1
  • 1
    How is your answer different than that of the one by eBusiness?
    – user40980
    Aug 10, 2015 at 13:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.