使用枚举值表示两个枚举值

本文关键字:枚举 两个 表示 | 更新日期: 2023-09-27 18:17:54

想象场景

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)
{
    ...

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

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

使用枚举值表示两个枚举值

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

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成员

如果您打算使用Flags enum,您应该使其自文档化

[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)
{
}

您可以通过以下方式实现这一点,通过我在问题下发布的链接示例,但使用非排他性标志值。注意,SavedWithChangesSavedWithoutChanges都包含位1,赋值给Saved

[Flags]
public enum SaveStates
{
    Saved = 1,
    SavedWithChanges = 3,
    SavedWithoutChanges = 5
}
if ((lastState & SaveStates.Saved) == SaveStates.Saved)
{
}
然而,这对其他开发人员来说可能相当不直观——通常标记枚举不是这样使用的。因此,显式地用所有枚举值声明所有条件可能会更具可读性。Konamiman发的好主意:
public static bool IsSaved(SaveStates state)
{
    return state == SaveStates.SavedWithChanges
        || state == SaveStates.SavedWithoutChanges;
}

结合了两个世界的优点:既满足了最少惊讶原则,又简洁易读。

如何更改枚举?

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

同时,它还提供了一个枚举值,可以作为"默认"值使用,这被认为是一种良好的、"干净的代码"实践。

我更喜欢这样:

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

这是非常直观的,每个开发人员都会理解的。

与其用一个enum来表示两件事,为什么不直接用两个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");
    }
}