1

我正在开发一个用 .NET 编写的遗留 Web 应用程序。在应用程序启动时,它会检查登录的用户类型,并根据用户类型确定要显示的 UI 元素。

现在实现的方式是一系列 if 语句来处理每个用户类型的情况,然后是一个函数调用,以根据用户类型将各种 UI 元素设置为可见或不可见。问题是函数调用有点混乱。大约有 500 行以下内容:

setTabsVisible(true, true, true, true, true, true, true, true, true, true, false, false);
if (!locked)
{
    setActionButtonsVisibile(true, false, true, "Submit", "");
    script += setTabsReadOnly(false, false, false, false, false, false, true, false, false, false, true, true);
    script += setSubTabsReadOnly(true, true, false, true, true, true, false, false, true, true, false, true);
}
script += setSubTabsVisible(false, false, false, false, false, false, true, false, false, true, true);

乍一看,所有这些真、真、假、真等都不是很可读。要查看正在打开或关闭的内容,您必须将鼠标悬停在函数上并将布尔值与参数列表匹配。

所以我在想一个更好的解决方案可能是一个位字段,它是由按位或一起的常量构建的。这样一个函数调用可能看起来更像这样:

setTabsReadOnly(notesTab | documentsTab | signoffTab | etc);

但是,C# 似乎不支持位域。有更好的解决方案吗?或者它甚至值得改变?

4

4 回答 4

6
[Flags]
public enum MyFlags : short
{
    Foo = 0x1,
    Bar = 0x2,
    Baz = 0x4
}

public static class Program
{
    public static void Main()
    {
        CheckFlags(MyFlags.Bar | MyFlags.Baz);
    }

    public static void CheckFlags(MyFlags flags)
    {
        if (flags.HasFlag(MyFlags.Foo))
            Console.WriteLine("Item has Foo flag set");

        if (flags.HasFlag(MyFlags.Bar))
            Console.WriteLine("Item has Bar flag set");

        if (flags.HasFlag(MyFlags.Baz))
            Console.WriteLine("Item has Baz flag set");
    }
}

如上例所示,您应该使用 Flag Enums 来简化您的代码。有关 Enums 的更多信息,请查看此参考。因此,在您的情况下,您将拥有:

public static void setTabsReadOnly(YourEnum flags)
{
    // Your Code
} 

setTabsReadOnly(YourEnum.NotesTab | YourEnum.DocumentsTab | YourEnum.SignoffTab);
于 2013-01-16T17:58:28.303 回答
4

听起来您需要创建一个Flags Enum. 您可以将方法修改为仅具有枚举参数,然后使用要应用的枚举类型调用该方法:

public void MyMethod(MyEnumeration myEnum) { ... }
...
MyMethod(MyEnumeration.First | MyEnumeration.Second | MyEnumeration.Third);

来自 MSDN 的示例:

您可以使用枚举类型来定义位标志,这使枚举类型的实例能够存储枚举器列表中定义的值的任意组合。

[Flags]
enum Days2
{
    None = 0x0,
    Sunday = 0x1,
    Monday = 0x2,
    Tuesday = 0x4,
    Wednesday = 0x8,
    Thursday = 0x10,
    Friday = 0x20,
    Saturday = 0x40
}
class MyClass
{
    Days2 meetingDays = Days2.Tuesday | Days2.Thursday;
}

http://msdn.microsoft.com/en-us/library/cc138362.aspx

于 2013-01-16T17:58:39.683 回答
3

但是,C# 似乎不支持位域。有更好的解决方案吗?

Flags枚举基本上是一个位域。

表示可以将枚举视为位域;即一组标志。

[FlagsAttribute] 
enum MultiHue : short
{
    Black = 0,
    Red = 1,
    Green = 2,
    Blue = 4
};

// Black and Red:
MultiHue mh = MultiHue.Black & MultiHue.Red;
于 2013-01-16T17:58:28.740 回答
2

您想要的是使用带有 Flags 属性的 Enum,

[Flags]
enum TabOptions
{
    notesTab = 0x01,
    documentsTab = 0x02,
    signoffTab = 0x04
}

然后,您可以按照您描述的方式将值或枚举值组合在一起。

void setTabsReadOnly(TabOptions options)
{
   //do stuff
} 

setTabsReadOnly(notesTab | documentsTab | signoffTab)

于 2013-01-16T18:00:23.370 回答