【问题标题】:Storing multiple values for an enum为枚举存储多个值
【发布时间】:2013-03-02 20:55:39
【问题描述】:
public enum ENUM_AccDebitCredit
{
    accDR = 1,
    accCR = 2
}

我在一个类中声明为public ENUM_AccDebitCreditDebitCredit { get; set; }

在我的代码中,我尝试从数据表中填充 enum,如下所示

DebitCredit = (ENUM_TransactionType)Enum.Parse(typeof(ENUM_TransactionType), rsACC_AccountingRules.Tables[0].Rows[0]["DR"].ToString()) & (ENUM_TransactionType)Enum.Parse(typeof(ENUM_TransactionType), rsACC_AccountingRules.Tables[0].Rows[0]["CR"].ToString());

我想在DebitCredit 中存储多个值,我该怎么做

我的数据表如下

DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("DR", typeof(string));
table.Columns.Add("CR", typeof(string));
table.Rows.Add(25, "1","2"); // enum values

【问题讨论】:

  • Enum Flags Attribute的可能重复
  • 如果您希望枚举的行为类似于标志,请使用 [Flags] 属性标记您的枚举。但是,您需要 1、2、4 之类的值(除非 Return 确实既是 Sales 又是 Purchase,这似乎不太可能)并使用 | 将它们组合起来
  • 如果您希望 DebitCredit 成为一个数组,请查看 stackoverflow.com/questions/7031299/…
  • 我需要从 Datatable 值中填写

标签: c# enums


【解决方案1】:

您可以拥有ENUM_TransactionType 的集合或使用[Flags] 将每个项目表示为位标志。

【讨论】:

    【解决方案2】:

    如果您的意思是希望枚举“混合”多于一个值,则需要将代码更改为:

    [Flags]
    public enum ENUM_TransactionType
    {
       None = 0,
       ttSales = 1,
       ttPurchase = 2,
       ttReturnIn = 4
    }
    

    另外,您需要使用按位 OR | 运算符而不是 AND &

    ENUM_TransactionType value = ENUM_TransactionType.ttSales | ENUM_TransactionType.ttPurchase;
    

    【讨论】:

    • 我需要从数据表中分配值是否可能
    • @Dotnet 当然。如果数据列是带有 flags 属性的枚举类型,并且您执行了整个| OR,则没有问题。
    • @MatíasFidemraizer 我会考虑将该属性设为可为空的值,而不是 None
    • @DanielA.White 那么当检查.None0 就足够时,您可能会出现不必要的空引用异常。
    • @DanielA.White Null 或“none”有不同的含义。 Null 是“未分配”,“none”是“无值”。在逐位操作中,您的提案增加了复杂性,因为如果它为空,我无法执行“SomeEnum.HasFlag(...)”。 None 在这种情况下更具语义。在其他情况下,我会使用 nullable。
    【解决方案3】:
    var DebitCredit = new List<ENUM_TransactionType>();
    DebitCredit.Add((ENUM_TransactionType)Enum.Parse(typeof(ENUM_TransactionType), rsACC_AccountingRules.Tables[0].Rows[0]["Drug"].ToString()));
    DebitCredit.Add((ENUM_TransactionType)Enum.Parse(typeof(ENUM_TransactionType), rsACC_AccountingRules.Tables[0].Rows[0]["Drug1"].ToString()));
    

    然后你可以测试:

    if (DebitCredit.Contains(ENUM_TransactionType.ttSales)) etc.
    

    【讨论】:

      【解决方案4】:

      关于您最近的编辑,以下是您的操作方式:

      public enum ENUM_AccDebitCredit
      {
          accDR = 1,
          accCR = 2
      }
      
      var type1 = (ENUM_AccDebitCredit)int.Parse(rsACC_AccountingRules.Tables[0].Rows[0]["DR"].ToString());
      
      var type2 = (ENUM_AccDebitCredit)int.Parse(rsACC_AccountingRules.Tables[0].Rows[0]["CR"].ToString());
      
      myClass.DebitCard = type1 | type2;
      

      您可以使用[Flags] 属性,也可以尝试以下方法:

      public enum ENUM_TransactionType
      {
          ttSales = 1,
          ttPurchase = 2,
          ttReturnIn = 4,
      }
      
      myClass.DebitCard = ENUM_TransactionType.ttSales | ENUM_TransactionType.ttReturnIn;
      
      bool hasSales = myClass.DebitCard & ENUM_TransactionType.ttSales > 0;
      

      DataTable 你可以试试这个:

      var type1 = (ENUM_TransactionType)Enum.Parse(typeof(ENUM_TransactionType), rsACC_AccountingRules.Tables[0].Rows[0]["Drug"].ToString());
      
      var type2 = (ENUM_TransactionType)Enum.Parse(typeof(ENUM_TransactionType), rsACC_AccountingRules.Tables[0].Rows[0]["Drug1"].ToString());
      
      myClass.DebitCard = type1 | type2;
      

      这是一个称为位掩码的过程。有关此过程背后的数学运算的更多信息,请参见此处:Bit Masking

      【讨论】:

      • 如何从datatable 分配myclass.DebitCard
      • 您好,谢谢,但ttSales and ttPurchase 中存储的值不是myclass.DebitCard,而是ttReturnIn
      • 您好,感谢您的回答,但显示的值不是3
      • @Dotnet 这是正确的。要测试一个值,你可以这样做:if(myClass.DebitCard &amp; ENUM_AccDebitCredit.accDR &gt; 0) { /* ... */ }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-09
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      相关资源
      最近更新 更多