HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

"String Enum" implementation - comments?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
enumimplementationstringcomments

Problem

I have a need to represent a finite set of discrete string values:

  • When these strings are used in code, they must belong to the valid set, or serious errors (or worse) can occur.



  • As "magic strings" are a terrible code smell, I want to encapsulate the strings within a non-string type, so that I can require the use of my type instead of just a string and thus enforce at compile-time that a value is given that I know will work.



  • No constants; if I change the string behind the scenes I should not have to recompile all usages of my type.



  • The identifiers representing the valid values should not have to have any formulaic similarity to the actual string (no Enum.ToString or similar).



  • Lastly, while I want to enforce the use of my type so I can restrict values to the ones I know are valid, the type must be easily convertible to a string so that the piece of code that really needs the string doesn't have to undergo a complicated or esoteric conversion.



What I came up with is a variation of a "multiton"; a class that cannot be instantiated in code, but has a finite number of static instances each representing a valid value of the type. They are implicitly convertible to strings and so the static members just drop in wherever a string is needed.

```
//abstract base; derive to create your specific set of values
public abstract class StringEnum
{
protected StringEnum(string name)
{
this.name = name;
}

private readonly string name;

public static implicit operator string(StringEnum sp)
{
return sp.name;
}
}

//one possible derivation
public class CommandNames:StringEnum
{
//unfortunately each derivation has to call back to the base constructor;
//it would be nice not to have to do this, but meh
protected CommandNames(string commName) : base(commName) { }

//obviously the instance names don't have to match the real string value exactly
public static readonly CommandNames DoSomething = new CommandName

Solution

A few things don't add up for me regarding your usage. You want compile time absolution, but dynamic values while stating the critical nature of its use.

One option:
You can just take care of this by having objects with inheritance structures and loading your "dynamic" values from an application configuration or db. Just have 3 layers of inheritance 1) StringEnum 2) Enum Declaration (like System638) and 3) actual values. Just wire up the inheritance. Mostly likely though, interfaces would be more appropriate for restrictions at the 1 & 2 layers.

Recommended (assuming the distributed smell of the use case):
Build your functional class and bind it to a single DB table that ensures the integrity you are looking for. Just cache the values in memory for performance needs.

Recommended (given the critical nature of its use)
Find a different way to design the system so that you can fully embed what you need in code. For example, a web service. Even if you need a local presence you can utilize a web service to control the pieces you need.

Context

StackExchange Code Review Q#10016, answer score: 2

Revisions (0)

No revisions yet.