C# 枚举和重复值 - 危险?

发布于 2024-07-30 07:14:12 字数 2722 浏览 2 评论 0原文

我想知道 C# 枚举以及重复值会发生什么。 我创建了以下小程序来测试:

namespace ConsoleTest
{

    enum TestEnum
    {
        FirstElement = -1,
        SecondElement,
        ThirdElement,
        Duplicate = FirstElement
    }

    /// <summary>
    /// Summary description for MainConsole.
    /// </summary>
    public class MainConsole
    {
        /// <summary>
        /// Constructor for the class.
        /// </summary>
        public MainConsole()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        /// <summary>
        /// Entry point for the application.
        /// </summary>
        /// <param name="args">Arguments to the application</param>
        public static void Main(string[] args)
        {
            TestEnum first = TestEnum.FirstElement;
            TestEnum second = TestEnum.SecondElement;
            TestEnum duplicate = TestEnum.Duplicate;

            foreach (string str in Enum.GetNames(typeof(TestEnum)))
            {
                Console.WriteLine("Name is: " + str);
            }

            Console.WriteLine("first string is: " + first.ToString());
            Console.WriteLine("value is: " + ((int)first).ToString());
            Console.WriteLine("second string is: " + second.ToString());
            Console.WriteLine("value is: " + ((int)second).ToString());
            Console.WriteLine("duplicate string is: " + duplicate.ToString());
            Console.WriteLine("value is: " + ((int)duplicate).ToString());

            TestEnum fromStr = (TestEnum)Enum.Parse(typeof(TestEnum), "duplicate", true);
            Console.WriteLine("fromstr string is: " + fromStr.ToString());
            Console.WriteLine("value is: " + ((int)fromStr).ToString());
            if (fromStr == TestEnum.Duplicate)
            {
                Console.WriteLine("Duplicate compares the same as FirstElement");
            }
            else
            {
                Console.WriteLine("Duplicate does NOT compare the same as FirstElement");
            }

        }
    }
}

它产生以下输出:

Name is: SecondElement
Name is: ThirdElement 
Name is: FirstElement
Name is: Duplicate
first string is: FirstElement
value is: -1
second string is: SecondElement
value is: 0
duplicate string is: FirstElement
value is: -1
fromstr string is: FirstElement
value is: -1
Duplicate compares the same as FirstElement
Press any key to continue . . .

这似乎正是我想要和期望的,因为我正在构建版本标记会经常增加的东西,所以我想要一些我可以的东西“分配”到当前版本,甚至进行比较。

但问题是:这种方法有什么陷阱? 有吗? 这只是糟糕的风格吗(我不想最终出现在 thedailywtf 上)? 有没有更好的方法来做这样的事情? 我使用的是 .NET 2.0,无法选择转到 3.5 或 4.0。

欢迎提出意见。

I was wondering about C# Enumerations and what happens with duplicate values. I created the following small program to test things out:

namespace ConsoleTest
{

    enum TestEnum
    {
        FirstElement = -1,
        SecondElement,
        ThirdElement,
        Duplicate = FirstElement
    }

    /// <summary>
    /// Summary description for MainConsole.
    /// </summary>
    public class MainConsole
    {
        /// <summary>
        /// Constructor for the class.
        /// </summary>
        public MainConsole()
        {
            //
            // TODO: Add constructor logic here
            //
        }
        /// <summary>
        /// Entry point for the application.
        /// </summary>
        /// <param name="args">Arguments to the application</param>
        public static void Main(string[] args)
        {
            TestEnum first = TestEnum.FirstElement;
            TestEnum second = TestEnum.SecondElement;
            TestEnum duplicate = TestEnum.Duplicate;

            foreach (string str in Enum.GetNames(typeof(TestEnum)))
            {
                Console.WriteLine("Name is: " + str);
            }

            Console.WriteLine("first string is: " + first.ToString());
            Console.WriteLine("value is: " + ((int)first).ToString());
            Console.WriteLine("second string is: " + second.ToString());
            Console.WriteLine("value is: " + ((int)second).ToString());
            Console.WriteLine("duplicate string is: " + duplicate.ToString());
            Console.WriteLine("value is: " + ((int)duplicate).ToString());

            TestEnum fromStr = (TestEnum)Enum.Parse(typeof(TestEnum), "duplicate", true);
            Console.WriteLine("fromstr string is: " + fromStr.ToString());
            Console.WriteLine("value is: " + ((int)fromStr).ToString());
            if (fromStr == TestEnum.Duplicate)
            {
                Console.WriteLine("Duplicate compares the same as FirstElement");
            }
            else
            {
                Console.WriteLine("Duplicate does NOT compare the same as FirstElement");
            }

        }
    }
}

Which produces the following output:

Name is: SecondElement
Name is: ThirdElement 
Name is: FirstElement
Name is: Duplicate
first string is: FirstElement
value is: -1
second string is: SecondElement
value is: 0
duplicate string is: FirstElement
value is: -1
fromstr string is: FirstElement
value is: -1
Duplicate compares the same as FirstElement
Press any key to continue . . .

This seems to be EXACTLY what I want and expect since I'm constructing something that a version tag will increment every so often, so I want something that I can "assign" to the current version, and even compare to it.

Here's the question though: what's the pitfalls of this approach? Is there one? Is it just bad style (I don't want to end up on thedailywtf)? Is there a lot better way of doing something like this? I'm on .NET 2.0 and do NOT have the option to go to 3.5 or 4.0.

Opinions are welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰火雁神 2024-08-06 07:14:12

我认为这没有什么问题,事实上有时也会做同样的事情。 有时,一个方法(尤其是随着时间的推移而增长的 APi 的本机 P/Invoke)可能会采用相同的数值,但它们的含义不同,因此我喜欢有一个描述用法的枚举值名称。

I see nothing wrong with it, and in fact do the same thing on occasion. There are times when a method (especially a native P/Invoke to an APi that has grown over time) may take in the same numerical values, but they mean something different, so I like to have an enumeration value name that describes the usage.

沉睡月亮 2024-08-06 07:14:12

目前尚不清楚您想要实现什么目标,但对我来说看起来不太好。 例如,在“Duplicate”之后向枚举添加另一个条目将采用值 0,除非您再次显式设置该值。

Its not clear what you're trying to achieve, but it doesn't look great to me. Adding another entry to the enum after 'Duplicate' for example will take the value 0 unless you explicitly set the value again.

悲歌长辞 2024-08-06 07:14:12

如果您有标志枚举,则提供别名枚举值可能会很有用。 例如,

[Flags]
enum Rows {
  Even = 0x01,
  Odd = = 0x02,
  All = Even | Odd
}

但是,如果您阅读 Cwalina 和 Abrams 的框架设计指南中的枚举指南,您会发现以下建议:

请勿将枚​​举用于开放集(例如操作系统版本、朋友的姓名等)。

请勿在枚举中包含标记值。

拥有当前版本是一个哨兵值。

这些准则适用于框架设计,如果您只想在应用程序内部使用枚举,那么违反这些准则可能并不重要。 但是,Microsoft 创建这些指南是为了避免其他开发人员必须使用您的代码时出现常见陷阱。

Providing alias enum values can be useful if you have a flags enum. E.g.

[Flags]
enum Rows {
  Even = 0x01,
  Odd = = 0x02,
  All = Even | Odd
}

However, if you read the guidelines for enums in Framework Design Guidelines by Cwalina and Abrams you will find the following advice:

DO NOT use an enum for open sets (such as the operating system version, names of your friends etc.).

and

DO NOT include sentinel values in enums.

Having a current version is a sentinel value.

These guidelines are for framework design and if you simply want to use the enum internally in your application it may not matter if you break these guidelines. However, Microsoft created these guidelines to avoid common pitfalls when other developers have to use your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文