24

我有一个带有枚举属性的类,如下所示:

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

public enum Color
{
    Red,
    Green,
}

现在可以像这样初始化这个类:

var foo = new Foo();

没有设置 ColorType 属性。现在,我正在尝试创建一个方法并对该枚举是否已设置执行操作,例如我有一个方法

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

但是我收到一个警告,说值永远不会为空,并且经过进一步研究,如果从未设置枚举,如果将默认为第一个值,在我的情况下为红色,我正在考虑向我的枚举添加一个值,这将被“未设置”并将该值设为第一个,因此如果尚未设置,则枚举将具有“未设置”值,是否有更好的方法来执行此操作,我提出的方法似乎会变得混乱

4

7 回答 7

44

您可以使用以下两种方法之一:默认枚举值或可为空的枚举。

默认枚举值

由于枚举由整数支持,并且int默认为零,因此枚举将始终默认初始化为等于零的值。除非您明确分配枚举值,否则第一个值将始终为零,第二个值将是一个,依此类推。

public enum Color
{
  Undefined,
  Red,
  Green
}

// ...

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

可空枚举

处理未分配枚举的另一种方法是使用可为空的字段。

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

// ...

var foo = new Foo();
Assert.IsNull(foo.Color);     // success!
于 2013-05-14T23:56:39.613 回答
6

您可以使基础私有字段可以为空,但属性不是。

例如

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; }
    }
}

这样,如果color == null您知道它尚未设置,并且您还阻止用户将其设置为null(或undefined其他答案指定)。如果colornull,您可以 100% 确定用户从未设置过它。

只有 catch 是返回的默认值,get但如果它更好地匹配您的程序,您总是可以抛出异常。

您还可以更进一步,使其set仅在给定值不等于默认值时设置字段(取决于您的用例):

public Color Color
{
    get { return _color ?? Color.Black; }
    set
    {
        if (value != Color)
        {
            _color = value;
        }
    }
}
于 2013-05-24T03:52:01.937 回答
3

你有两个真正的选择。第一种是给枚举添加一个未定义的值。这将是属性初始化之前的默认值。

1)

public enum Color
{
    Undefined,
    Red,
    Green,
}

使用您的支票,例如:

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

2)或者,您不能添加未定义的值而只创建属性Nullable

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

并执行您的检查,例如:

private void checkEnum(Foo foo)
{
    if(!foo.ColorType.HasValue)
    {
        //perform these actions
    }else
    {
        //perform those actions
    }
}
于 2013-05-14T23:58:33.073 回答
2

枚举是值类型,这意味着它们不是对存储在其他地方的对象的引用,因此它们不能是null. 它们总是有一个默认值,就像int在创建时默认为零一样。我建议两种方法:

  1. 添加另一个名为 eg 的枚举条目,None其值为零。这样,您的枚举值将默认为None创建时。然后你可以检查if(foo.ColorType != Color.None)

  2. 使您的Color财产成为可以为空的财产,例如:public Color? ColorType { get; set; }. 现在它将默认为null并且可以分配 value null。在此处阅读有关nullable类型的更多信息:MSDN - Nullable Types (C#)

于 2013-05-14T23:55:45.827 回答
0

enum是值类型所以不能为null,存储一般是整数。如果您想为您的类型定义一个未定义的值,您可能有

public enum Color
{
    Undefined,
    Red,
    Green,
}
于 2013-05-14T23:53:18.843 回答
0

正如您所发现的,C# 中的枚举是值类型(它们本质上是整数)而不是引用类型,因此它们不会默认为 NULL,而是枚举中的最低整数值。在处理枚举时不要忽视这种关系,因为它是它们最有用的属性之一。永远记住,无论你是否明确声明,

public enum Color
{
    Red,
    Green
}

相当于:

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

尽管您当然可以为每个枚举成员提供您喜欢的任何整数值。

至于是否有更好的方法来做到这一点,这实际上完全取决于“this”是什么,尽管您建议简单地使用以下枚举设置并没有错:

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

通常,当您希望能够按名称从中选择一组绝对有限且离散的可能值时,您希望使用枚举。例如,假设我有一个将 4 个基本方向(北、东、南、西)之一作为参数的方法。我决定要按顺时针顺序对每个方向进行编号,从 0 开始表示北。

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

现在,与其让我的函数接受一个整数参数并相信我会记住每个数字所指的内容,我现在可以让该函数接受一个枚举成员作为参数并立即知道我正在处理的方向。例如:

getNeighbor(1);

读起来容易得多:

getNeighbor(Direction.East);
于 2013-05-14T23:54:23.650 回答
0

试试这个 :

private void checkEnum(Color color)
{
    if(string.IsNullOrEmpty(color.ToString()))
    {
        //value is not set
    }
     else
    {
        //value is set
    }
}
于 2022-02-14T14:15:53.333 回答