How to tell if an enum property has been set? C#

て烟熏妆下的殇ゞ 提交于 2019-12-23 06:48:06

问题


I have a class with an enum property like so:

public class Foo
{
    public Color ColorType {get;set;}
}

public enum Color
{
    Red,
    Green,
}

Now this class can be initialized like so:

var foo = new Foo();

without the ColorType property ever being set. Now, I'm trying to create a method and perform actions on whether that enum was ever set or not, for example I have a method

private void checkEnum(Foo foo)
{
    if(foo.ColorType !=null)
    {
        //perform these actions
    }else
    {
        //perform those actions
    }
}

however I get a warning saying that value will never be null and upon further research, if the enum is never set if will default to the first value which would be Red in my case, I was thinking about adding a value to my enum which would be 'not set' and make that value the first one, so if it hasnt been set then the enum will have the value 'not set', is there a better way of doing this, my proposed method seems like it could get messy


回答1:


You can use one of two methods: default enum value or a nullable enum.

Default enum value

Since an enum is backed by an integer, and int defaults to zero, the enum will always initialize by default to the value equivalent to zero. Unless you explicitly assign enum values, the first value will always be zero, second will be one, and so on.

public enum Color
{
  Undefined,
  Red,
  Green
}

// ...

Assert.IsTrue(Color.Undefined == 0);  // success!

Nullable enum

The other way to handle unassigned enum is to use a nullable field.

public class Foo
{
   public Color? Color { get; set; }
}

// ...

var foo = new Foo();
Assert.IsNull(foo.Color);     // success!



回答2:


You can make it so that the underlying private field is nullable, but the property is not.

E.g.

class SomeClass
{
    private Color? _color; // defaults to null

    public Color Color
    {
        get { return _color ?? Color.Black; }
        set { _color = value; }
    }

    public bool ColorChanged
    {
        get { return _color != null; }
    }
}

That way if color == null you know it hasn't been set yet, and you are also stopping the user from setting it to null (or undefined as other answers specify). If color is null you have 100% certainty that the user has not set it ever.

Only catch is the default value returned by the get but you could always throw an excepting if it better matches your program.

You can also take it one step further by making it so that the set only sets the field if the given value is not equal to the default value (depending on your use case):

public Color Color
{
    get { return _color ?? Color.Black; }
    set
    {
        if (value != Color)
        {
            _color = value;
        }
    }
}



回答3:


You have two real options. The first is to add an undefined value to enum. This will be the default value before the property is initialized.

1)

public enum Color
{
    Undefined,
    Red,
    Green,
}

With your check like:

private void checkEnum(Foo foo)
{
    if(foo.ColorType == Color.Undefined)
    {
        //perform these actions
    }else
    {
        //perform those actions
    }
}

2) Alternatively you can not add the undefined value and just make the property Nullable

public class Foo
{
    public Color? ColorType {get;set;}
}
public enum Color
{
    Red,
    Green,
}

And perform your check like:

private void checkEnum(Foo foo)
{
    if(!foo.ColorType.HasValue)
    {
        //perform these actions
    }else
    {
        //perform those actions
    }
}



回答4:


Enums are Value Types, which means they are not references to an object stored somewhere else, and hence they cannot be null. They always have a default value just like int which will default to zero upon creation. I suggest two approaches:

  1. Add another enum entry called e.g., None with value equal to zero. This way your enum value will default to None upon creation. Then you can check if(foo.ColorType != Color.None).

  2. Make your Color property a nullable one like: public Color? ColorType { get; set; }. Now it will default to null and can be assigned the value null. Read more about nullable types here: MSDN - Nullable Types (C#).




回答5:


As you've discovered, enumerations in C# are value types (they are essentially integers) not reference types so they will not default to NULL but rather the lowest integer value in the enumeration. Don't lose sight of this relationship when dealing with enums as it's one of their most useful attributes. Always remember that whether you explicitly state it or not,

public enum Color
{
    Red,
    Green
}

equates to:

public enum Color
{
    Red = 0,
    Green = 1
}

Though you may of course give each enumeration member any integer value that you like.

As far as whether or not there is a better way of doing this, it really all depends on what "this" is, though there's nothing wrong with your suggestion of simply using the following enum setup:

public enum Color
{
    None = 0,
    Red,
    Green
}

Generally you want to use enums when you have a decidedly finite and discrete set of possible values that you want to be able to select from by name. For example, say I have a method that takes one of the 4 cardinal directions (North, East, South, West) as a parameter. I decide that I want to number each of the directions in clockwise order, starting with 0 for North.

public enum Direction
{
    North = 0,
    East,
    South,
    West
}

Now, instead of having my function take an integer parameter and trusting that I'll remember what each number refers to, I can now have the function take an enumeration member as a parameter and know immediately which direction I'm dealing with. For example:

getNeighbor(1);

reads much easier as:

getNeighbor(Direction.East);



回答6:


enum is a value type so it cannot be null, and the storage is generally an integer. If you want a undefined value for your type, you may have

public enum Color
{
    Undefined,
    Red,
    Green,
}


来源:https://stackoverflow.com/questions/16554577/how-to-tell-if-an-enum-property-has-been-set-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!