如何将枚举类型设置为null

236

我有一个枚举类型

string name;

public enum Color
{
  Red,
  Green,
  Yellow
}
如何在加载时将其设置为NULL。
name = "";
Color color = null; //error

更新: 我的错误,我没有正确解释清楚。但是所有与可空相关的答案都是完美的。我的情况是如果我在一个类中有其他元素(如名称等)的枚举get/set,那么该怎么办?在页面加载时,我初始化类并尝试将值默认为null。以下是场景(代码用C#编写):

namespace Testing
{
    public enum ValidColors
    {
        Red,
        Green,
        Yellow
    }

    public class EnumTest
    {
        private string name;
        private ValidColors myColor;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public ValidColors MyColor
        {
            get { return myColor; }
            set { myColor = value; }
        }

    }

    public partial class _Default : System.Web.UI.Page
    {       
        protected void Page_Load(object sender, EventArgs e)
        {
            EnumTest oEnumTest = new EnumTest();
            oEnumTest.Name = "";
            oEnumTest.MyColor = null; //???
        }
    }

}

接着使用下面的建议,我修改了上面的代码以便使用get和set方法。在EnumTest类中,在声明私有枚举变量和get/set方法时,我只需要添加“?”:

public class EnumTest
{
    private string name;
    private ValidColors? myColor; //added "?" here in declaration and in get/set method

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public ValidColors? MyColor
    {
        get { return myColor; }
        set { myColor = value; }
    }

}

感谢大家提供的建议。


可能是C#枚举:可空或“未知”值?的重复问题。 - Michael Freidgeim
9个回答

442

你可以使用“?”运算符来表示可空类型。

public Color? myColor = null;

或者使用枚举的标准做法,对于不能为null的枚举类型,在枚举中将第一个值(即0)作为默认值。例如,在颜色为空的情况下。

public Color myColor = Color.None;

@equiman 不需要进行强制类型转换,因为类型已经在左侧指定,你基本上是在重复我的已被接受的答案的第一部分。 - Rodney S. Foley
13
这回答了我的问题:“你能否在枚举名称后面添加'?'来使其可为空?” - LuckyLikey
2
对于那些已经在他们的类中声明了可空类型并来到这里的人:myColor = (Color?)null; - StefanJanssen
@StefanJanssen 如果已经声明了可空的Color类型,那么你不需要强制转换null,只需要使用myColor = null就可以了。 - Rodney S. Foley
@StefanJanssen 在最新的VS2017和VS2019中,我没有编译器错误。你可能在csproj文件中设置了某些触发此问题的内容。如果您可以创建一个独立的项目,并使用内置枚举(如上面示例中的Color)重现该问题并共享它,那将很酷。同时,请分享完整的编译器错误,包括错误编号。 - Rodney S. Foley
显示剩余2条评论

54
如果这是C#,它不起作用:枚举是值类型,不能为null。
通常的做法是添加一个None成员。
public enum Color
{
  None,
  Red,
  Green,
  Yellow
}

Color color = Color.None;

...或者使用 Nullable

Color? color = null;

27

将你的变量变为可为空。例如:

Color? color = null;
或者
Nullable<Color> color = null;

15

枚举是C#中的“值”类型(这意味着枚举被存储为其本身的任何值,而不是指向存储该值本身的内存位置的引用)。您无法将值类型设置为null (因为null仅用于引用类型)。

尽管如此,您可以使用内置的Nullable<T>类,它包装了值类型,以便您可以将它们设置为null,检查它是否有值并获取其实际值。这两个方法都是Nullable<T>对象的方法。

name = "";
Nullable<Color> color = null; //This will work.

还有一个可以使用的快捷方式:

Color? color = null;

这与Nullable<Color>相同;


8

在使用Nullable枚举作为类/方法变量和类属性时,一些观察点和问题需要注意:


在C# v7.3中(tested on .NET v4.7.2 with VS2019),这段代码是有效的:

Color? color = null; // works

但是这不行:
Color? color = condition ? Color.Red : null;

// Error CS8370 
// Feature 'target-typed conditional expression' is not available in C# 7.3.  
// Please use language version 9.0 or greater.

解决方法是将null进行类型转换:
Color? color = condition ? Color.Red : (Color?)null; // works

此外,将变量命名为Color,即与类型完全相同的情况下,仅在类型为非可空时有效
Color Color = condition ? Color.Red : Color.None; // works fine!

但是当类型为 Nullable 时,它却表现不佳。
Color? Color = condition ? Color.Red : (Color?)null;

// Error CS0165 Use of unassigned local variable 'Color'
// Error CS1061 'Color?' does not contain a definition for 'Red' 
// and no accessible extension method 'Red' accepting a first argument of type 'Color?' 
// could be found (are you missing a using directive or an assembly reference?)

解决方法是使用带有命名空间的类型的完全限定名称:
Color? Color = condition ? MyEnums.Color.Red : (Color?)null; // works now

但最好遵循变量名称的小写命名的标准做法:

Color? color = condition ? Color.Red : (Color?)null; // works now

在类级别上,也存在类似的问题:
class Program {
    Color? Color => Condition ? Color.Red : (Color?)null;
}

// Error CS1061 'Color?' does not contain a definition for 'Red' 
// and no accessible extension method 'Red' accepting a first argument of type 'Color?' 
// could be found (are you missing a using directive or an assembly reference?)

解决方法是完全限定类型:

Color? Color => Condition ? MyEnums.Color.Red : (Color?)null; // works now

1
刚刚挽救了一天! - Jesse Q
讲解得非常清楚!解决了我的问题。非常感谢。 - Umar T.

3
我假设你在使用c ++。如果你使用c#,答案可能是相同的,但语法会有些不同。 枚举是一组int值。它不是对象,所以你不应该将其设置为null。将某物设置为null意味着你正在将指针指向对象的地址零。你不能真正用int做到这一点。你想要做的是将int设置为一个通常没有的值,以便您可以判断它是否是一个好的值。 因此,请将您的颜色设置为-1。
Color color = -1;

或者,你可以从1开始枚举并将其设置为零。如果你像现在这样将颜色设置为零,那么你将会把它设置为“红色”,因为在你的枚举中,红色是零。

因此,

enum Color {
red =1
blue,
green
}
//red is 1, blue is 2, green is 3
Color mycolour = 0;

0
这样做是否更好,明确地将值0分配给None常量?为什么?
因为默认的enum值等于0,如果您调用default(Color),它会打印None
因为它在第一位置,将字面值0分配给任何其他常量都会改变该行为,同时改变出现顺序也会改变default(Color)的输出(https://dev59.com/gW445IYBdhLWcg3wO31u#4967673)。

0
Color? color = null;

或者你可以使用

Color? color = new Color?();

无法使用赋值 null 的示例

color = x == 5 ? Color.Red : x == 9 ? Color.Black : null ; 

所以你可以使用:

 color = x == 5 ? Color.Red : x == 9 ? Color.Black : new Color?(); 

-1

它的样例就像这样完成

public enum Colors
 {
  None,
  Red,
  Green,
  Yellow
   }

  Color colors = Colors.null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接