We are representing something by string derived from two enums in a lot of places in code (including in graphs and maps) which would be better represented by a custom type which is constructed from the enums and can indicate that it is one or the other (but never both), with the addition of an integer index to indicate if there are more than one of these created.
To give a concrete example:
enum FirstEnum
{
A,
B,
C,
... (many others here)
}
enum SecondEnum
{
G,
H,
I,
...(others here)
}
Now I want a type which encapsulates these two enums but indicates clearly which one of these it is.
I created a class which represents this using an Either struct borrowed from Haskell:
public class CustomTypeId : IEquatable<CustomTypeId>
{
private readonly IEither<FirstEnum, SecondEnum> _customType;
public readonly int Index = 1;
public CustomTypeId()
: this(FirstEnum.None)
{
}
public CustomTypeId(FirstEnum firstEnum)
{
_customType = Either.Left<FirstEnum, SecondEnum>(firstEnum);
IsSecondType = false;
IsDefault = firstEnum == FirstEnum.None;
}
public CustomTypeId(SecondEnum secondEnum, int index = 1)
{
_node_type = Either.Right<FirstEnum, SecondEnum>(secondEnum);
IsSecondType = secondEnum != SecondEnum.None;
IsDefault = secondEnum == SecondEnum.None;
Index = index;
}
}
...
I also created a builder with an interface like this to create the type based on string:
public interface ICustomTypeIdBuilder
{
CustomTypeId Build(string node_name);
}
this is then injected everywhere ComponentId is built from string.
Now first of all, I'm not convinced that this is the best way to represent this type of thing, and it feels slightly unclean to me.
The other issue I have is I need a way to also allow instantiation of CustomTypeId by enum but the company I work for are strictly opposed to direct instantiation and require such things to be injected.
This eliminates the option to have static properties in the ComponentTypeId such as:
public static CustomTypeId None { get; } = new CustomTypeId(FirstEnum.None);
public static CustomTypeId A { get; } = new CustomTypeId(FirstEnum.A);
...
The only option I can think of is to have additional methods on ICustomTypeIdBuilder such as
CustomTypeId Build(FirstEnum firstEnum);
CustomTypeId Build(SecondEnum secondEnum);
...
which makes the solution quite unclean in my opinion...
Alternatively I also thought about the solution to create classes deriving ICustomTypeId, but this would mean that I would have to create 30+ classes just to represent something quite simple...
Aucun commentaire:
Enregistrer un commentaire