1

How can a property in a C# class be set to only be allowed to have either of two strings?

For example, consider this class:

class Route
{
    private string color;
}

If I want color to only be allowed to be "Dark red" or "Light blue", how can I do this?

I tried defining an enum something like this:

public enum Color
{
    "Dark red",
    "Light blue"
}

And then use it instead of using the built in string class, but it doesn't seem like the correct way..

Stephen Johnson
  • 517
  • 1
  • 4
  • 12
  • 2
    `but it doesn't seem like the correct way.` What makes you think that? Enum is fine. – Equalsk May 11 '17 at 09:34
  • You can also use the `DescriptionAttribute`, see: https://stackoverflow.com/questions/2650080/how-to-get-c-sharp-enum-description-from-value – Jazz. Mar 01 '23 at 16:56

3 Answers3

7

Enums in C# consist of enum literals, not string literals.

What you basically need is

public enum ColorEnum
{
    DarkRed,
    LightBlue
}

and then your property looks like this:

public ColorEnum Color { get; set; }

Please take a look at the reference for C# enums here: https://learn.microsoft.com/en-us/dotnet/articles/csharp/language-reference/keywords/enum

If you must also have a property of type string, you could implement a property which converts between your enum values and strings:

public string ColorAsString
{
    get => Color.ToString();
    set => Color = (ColorEnum)Enum.Parse(typeof(ColorEnum), value);
}
Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • 3
    You could combine this with `DescriptionAttribute`'s on each enum value for the string representation. – Jamiec May 11 '17 at 09:36
3

An alternative to using an enum could be something like this:

public class ColorString
{
    private readonly string _value;

    public static ColorString DarkRed = new ColorString("Dark red");
    public static ColorString LightBlue = new ColorString("Light blue");

    private ColorString(string value)
    {
        _value = value;
    }

    public override string ToString()
    {
        return _value;
    }
}

This is equivalent to the enum but retains the string's value and allows you to add additional behaviour to the type.

If you are feeling ambitious, you can even allow it to be treated as a string with:

public static implicit operator string(ColorString colorString)
{
    return colorString.ToString();
}

Though this should be treated with caution.

If it really has to be a string, you could add a runtime check on setting the value via the property setter. Something like:

public class Route
{
    private string _color;
    private readonly ISet<string> _validColors
        = new HashSet<string> {"Dark red", "Light blue"};

    public string Color
    {
        get { return _color; }
        set
        {
            if (_validColors.Contains(value))
                _color = value;
            else
                throw new ArgumentException("Invalid color");
        }
    }
}

This doesn't stop the value being set directly on _color though.

Scroog1
  • 3,539
  • 21
  • 26
0

Properties have getters and setters. If your requirement is to limit the property to specific values you can use an enum:

class Route
{
    private Color Color { get; set; }
}

public enum Color
{
    DarkRed,
    LightBlue
}

If it must be restricted to 2 string values:

class Route
{
    private string _color;
    public string Color
    {
        get
        {
            return _color;
        }
        set
        {
            switch (value)
            {
                case "First Valid Value":
                case "Second Valid Value":
                    _color = value;
                    break;
                default:
                    throw new ArgumentException("Invalid Value specified");
            }
        }
    }
}
Andrew Harris
  • 1,419
  • 2
  • 17
  • 29