【问题标题】:Initial Value of an Enum枚举的初始值
【发布时间】:2023-04-01 17:50:02
【问题描述】:

我有一个属性是枚举的类

枚举是

/// <summary>
/// All available delivery actions
/// </summary>
public enum EnumDeliveryAction
  {
    /// <summary>
    /// Tasks with email delivery action will be emailed
    /// </summary>
    Email,

    /// <summary>
    /// Tasks with SharePoint delivery action 
   /// </summary>
   SharePoint
  }

当我创建这个类的实例时,在代码中的NOWHERE,我是否指定了枚举字段的值,但它似乎默认为枚举列表中的第一项,而不是空值,这就是枚举工作?如果未设置枚举,如何确保它获得某种空值,我不希望它默认为枚举中的第一个值。

【问题讨论】:

  • 枚举是值类型,而不是引用类型。引用类型将默认为 null,而值类型将默认为一个值。 IE。 int 默认为 0,日期时间默认为最小日期等。

标签: c# enums


【解决方案1】:

enum 类型的默认值为0(默认为枚举中的第一个元素)。类的字段将被初始化为默认值。

如果您需要在枚举中表示 unknown 值,您可以添加一个值为 0 的元素 Unknown。或者,您可以将该字段声明为 Nullable&lt;MyEnum&gt; (MyEnum?) .

【讨论】:

  • 那么我需要以 1 开始我的枚举第一个值吗?
  • 除非您希望未定义默认值。否则它仍将默认为零值,如果您的枚举没有值为零的成员,则该值将是非法值..
  • 查尔斯:不是非法。在 C#(与 Java 不同)中,枚举值超出定义范围是合法的。
  • 这是合乎逻辑的违法行为。但这无关紧要。回到正轨,如果您的 enum 中没有名称为 None 的元素,FxCop 会抱怨。大概这是您的默认 0 值。养成好习惯。
  • @LeakyCode,恕我直言,NotSet 而不是 Unknown 是更好的选择。
【解决方案2】:

枚举是一种值类型,就像整数一样。您需要使其可以为空,以免默认为第一个(或 0 定义的)枚举成员。

public class MyClass
{
   public EnumDeliveryAction? DeliveryAction { get; set;}
}

【讨论】:

  • 或者添加一个未定义的成员:public enum EnumDeliveryAction {Undefined=0, Email=1, Sharepoint=2 }
  • 北极星:Nullable&lt;T&gt;T? 相同。
  • 是的。吨?等同于 Nullable.
【解决方案3】:

枚举字段初始化为零;如果您未在枚举中指定值,则它们从零开始(Email = 0SharePoint=1 等)。

因此,默认情况下,您自己初始化的任何字段都是Email。对于这种情况,添加None=0 比较常见,或者使用Nullable&lt;T&gt;;即

/// <summary>
/// All available delivery actions
/// </summary>
public enum EnumDeliveryAction
{
    /// <summary>
    /// Not specified
    /// </summary>
    None,

    /// <summary>
    /// Tasks with email delivery action will be emailed
    /// </summary>
    Email,

    /// <summary>
    /// Tasks with SharePoint delivery action 
   /// </summary>
   SharePoint
}

您还应该确保永远不要将您的最后一个 预期 值视为默认值;即

switch(action) {
    case EnumDeliveryAction.Email; RunEmail(); break;
    default: RunSharePoint(); break;
}

这应该是:

switch(action) {
    case EnumDeliveryAction.Email; RunEmail(); break;
    case EnumDeliveryAction.SharePoint; RunSharePoint(); break;
    default: throw new InvalidOperationException(
          "Unexpected action: " + action);
}

【讨论】:

    【解决方案4】:

    最佳实践(如代码分析所建议的那样)是在您的枚举中始终有一个默认值,它表示一个未设置的值。

    所以在你的情况下,你可能有:

    public enum EnumDeliveryAction
       {
    
        /// <summary>
        /// Default value
        /// </summary>
        NotSet,
    
        /// <summary>
        /// Tasks with email delivery action will be emailed
        /// </summary>
        Email,
    
        /// <summary>
        /// Tasks with SharePoint delivery action 
       /// </summary>
       SharePoint
      }
    

    顺便说一句,您不应该在枚举名称前加上 Enum。您可以考虑改为:

    public enum DeliveryAction;
    

    【讨论】:

    • 我不太确定我是否同意在 .Net 中添加“未定义”枚举成员,因为这就是 null 定义的含义 - 未知。在您创建的每个枚举中重新定义 null 似乎是多余的。
    • 在我看来,在枚举中使用默认值比使用可为空的枚举更好。
    【解决方案5】:

    枚举是值类型。值类型不能为空,初始化为0。

    即使你的枚举没有 0,枚举变量也会被初始化为 0。

    public enum SomeEnum
    {
        A = 1,
        B = 2
    }
    

    (稍后)

    SomeEnum x = default(SomeEnum);
    Console.WriteLine(x);
    

    输出 - 0


    一些回答者提倡使用Nullable&lt;T&gt; 来满足您的初始化期望。小心这个建议,因为Nullable&lt;T&gt; 仍然是一个值类型,并且具有与引用类型不同的语义。例如,它永远不会生成空引用异常(它不是引用)。

    SomeEnum? x = default(SomeEnum?);
    
    if (x == null)
    {
        Console.WriteLine("It's null!");
    }
    if (x > SomeEnum.B)
    {
    }
    else
    {
        Console.WriteLine("This runs even though you don't expect it to");
    }
    

    【讨论】:

      【解决方案6】:

      您可以从任何值(例如 1)开始枚举,但是当它们表示数据库中的查找值时,您通常希望它们匹配。

      根据 .Net Framework 设计指南,我通常将第一个 Enum 声明为 None (= 0)。

      【讨论】:

        【解决方案7】:

        向通常没有空值的值添加空值的传统方法是将变量声明为可空类型,即:

        EnumDeliveryAction? action=null;
        

        【讨论】:

          【解决方案8】:

          我建议将 None = 0 作为您的第一个枚举值。让它明确,然后你肯定知道它的价值是什么。

          【讨论】:

            【解决方案9】:

            默认情况下,只有引用类型是可为空的类型。如果您希望变量允许为空,则必须使用“?”将其定义为可为空的。字符(为此,您需要 C# 2.0 或更高版本)。

            enum MyEnum
            {
                ValueOne,
                ValueTwo
            }
            

            在你的班级里

            MyEnum? myvariable = null;
            

            【讨论】:

            • 我认为您的意思是只有 引用类型 默认情况下可以为空,因为引用和值类型在 .NET 中都被视为对象
            【解决方案10】:

            我在大学的 C++ 老师(11 年前)告诉我链接器将 enum 替换为它们的实际类型:

            typedef static const int enum;

            因此,任何时候你写像enum MY_VAL = 5; 这样的东西,你都可以很容易地用static const int MY_VAL = 5; 替换(但这只会让你的代码更长......)。

            反正任何int的默认值都是0。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-06-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多