【问题标题】:Using an enum value to represent two enum values使用一个枚举值来表示两个枚举值
【发布时间】:2015-10-15 11:26:11
【问题描述】:

描绘场景。

public enum SaveStates
{
    Saved,               //Represents a successful save.
    SavedWithChanges,    //Represents a successful save, where records were modified
    SavedWithoutChanges  //Represents a successful save, but no records were modified
}

在这种情况下,如果枚举是SavedWithChanges SavedWithoutChanges,则可以认为枚举是Saved

如果我有这样的变量:

SaveStates lastState = SaveStates.SavedWithoutChanges;

理想情况下,我想做这样的事情:

if (lastState == SaveStates.Saved)
{
    //The state is saved, do something awesome.
}

我当然可以这样做:

if (lastState == SaveStates.SavedWithChanges || lastState == SaveStates.SavedWithoutChanges)
{
    ...

但是这有点乏味,我不能假设其他开发人员会理解如何正确使用枚举。

每个枚举都是必需的,因为在某些情况下,我们可能想要在没有更改的保存事件中做一些特定的事情。

我对替代设计想法持开放态度。

【问题讨论】:

  • 我认为其他开发人员不会理解这一点。 Imo 这比使用 flags 属性更清楚。
  • 你的枚举不应该有一个未保存的值吗?否则为什么要检查它是否已保存,您只需使用Enum.IsDefined

标签: c# .net enums


【解决方案1】:

如果你担心代码的可读性,你可以使用这样的小扩展方法:

public static class SaveStatesExtension
{
    public static bool IsSavedState(this SaveStates state) {
        return state == SaveStates.SavedWithChanges || 
               state == SaveStates.SavedWithoutChanges;
    }
}

那么你的使用例子就变成了:

if (lastState.IsSavedState())
{
    //The state is saved, do something awesome.
}

当然,在这种情况下不再需要枚举中的Saved 成员。

【讨论】:

    【解决方案2】:

    如果您打算使用 Flags 枚举,您应该让它自我记录

    [Flags]
    public enum SaveStates
    {
        Saved = 1,
        WithChanges = 2,
        SavedWithoutChanges = Saved, // a bit pointless! Its the same as Saved
        SavedWithChanges = Saved | WithChanges  // has value "3"
    }
    

    然后,根据其他答案

    if ((lastState & SaveStates.Saved) == SaveStates.Saved)
    {
    
    }
    

    【讨论】:

    • 是我还是你做这些标志完全错误。使用标志时,您应该使用所有组件。并将Saved 设为Saved = With | Without
    • 支持这个答案。对我来说,更直观的是,“保存”和“已更改”是两件不同的事情。将它们放入一个枚举会导致部分混乱。我可能会更进一步,并拥有保存状态和更改状态的属性。为什么我会这样想?当您保存带有更改的内容,然后进行更改并再次保存时,您会怎么做?在确定要选择的新枚举时,您必须评估是否进行了先前的更改。其他所有内容都可以封装到扩展方法中,以根据需要设置/获取这些值。
    • @kevintjuh93 - 是你 ;)
    • @Jamiec 但说真的...Savedwith and without 的变化。所以应该反过来。
    • @kevintjuh93 这是否是一个好的方案取决于 OP,我同意它可能不是表示某物已保存状态的最佳方式。这个答案试图表明,虽然它可能与 Flags 枚举(根据我之前的答案)有一种方法可以做到这一点,但要添加一定程度的自我文档到代码。
    【解决方案3】:

    您可以通过我在问题下发布的链接示例实现此目的,但使用非排他性标志值。请注意,SavedWithChangesSavedWithoutChanges 都包含位 1,分配给 Saved

    [Flags]
    public enum SaveStates
    {
        Saved = 1,
        SavedWithChanges = 3,
        SavedWithoutChanges = 5
    }
    
    if ((lastState & SaveStates.Saved) == SaveStates.Saved)
    {
    
    }
    

    但是,这对于其他开发人员来说可能是相当不直观的 - 通常标志枚举不以这种方式使用。因此,使用所有枚举值明确说明所有条件可能更具可读性。好主意posted by Konamiman:

    public static bool IsSaved(SaveStates state)
    {
        return state == SaveStates.SavedWithChanges
            || state == SaveStates.SavedWithoutChanges;
    }
    

    结合了两全其美:principle of least astonishment 在简洁易读的同时感到满意。

    【讨论】:

      【解决方案4】:

      改变你的枚举怎么样?

      public enum SaveStates
      {
          NotSaved,               //Represents "not saved" state
          SavedWithChanges,    //Represents a successful save, where records were modified
          SavedWithoutChanges  //Represents a successful save, but no records were modified
      }
      

      在这种情况下,您可以将否定用于您所说的目的:

      if (lastState != SaveStates.NotSaved)
      {
          //The state is saved, do something awesome.
      }
      

      此外,它还为您提供了一个枚举值,可用作“默认”值,这被认为是一种良好的“干净代码”实践。

      【讨论】:

        【解决方案5】:

        我更喜欢这个:

        SaveStates[] savedWithOrWithoutChanges = { SaveStates.SavedWithChanges, SaveStates.SavedWithoutChanges };
        if (savedWithOrWithoutChanges.Contains(lastStat))
        {
            ...
        }
        

        这很直观,每个开发者都会明白。

        【讨论】:

          【解决方案6】:

          为什么不使用两个 bool 值而不是一个枚举来表示两件事。一个指示它是否已保存,另一个指示它是否“有更改”。如果第一个是假的,那么你就忽略第二个。

          private bool saved;
          
          private bool withChanges;
          
          public void SomeMethod()
          {
              if (saved)
              {
                  Console.WriteLine("Saved");
          
                  if (withChanges)
                  {
                      Console.WriteLine("With Changes");
                  }
                  else
                  {
                      Console.WriteLine("Without Changes");
                  }
              }
              else
              {
                  Console.WriteLine("Not saved");
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2018-03-16
            • 2019-01-29
            • 2021-10-21
            • 2012-11-17
            • 1970-01-01
            • 1970-01-01
            • 2014-09-21
            • 1970-01-01
            • 2010-09-11
            相关资源
            最近更新 更多