gpt4 book ai didi

c# - 如何在 C# 中处理枚举 0(CA1008 讨论)

转载 作者:行者123 更新时间:2023-11-30 14:21:33 28 4
gpt4 key购买 nike

规则 CA1008指定所有枚举都应具有 0 值,该值应命名为 Unknown(我们不在此处讨论标志)。我理解您想防止未初始化的值自动获得意义的原因。假设我定义了以下枚举:

enum Gender
{
Male,
Female
}

class Person
{
public string Name { get; set; }
public Gender Gender { get; set; }
}

这指定每个人都应该是男性或女性(让我们暂时不讨论性别)。如果我忘记设置 Gender 属性,那么此人将自动为男性,这可能会导致问题。出于这个原因,我理解 CA1008 警告,因此应该为未知/未初始化的值保留 0 值。

因此,让我们将 Gender 枚举更改为并且不再使用 0 值:

enum Gender
{
Male = 1,
Female = 2
}

当我不指定性别时,此人既不是男性也不是女性。序列化过程中可能会出现问题。在调试期间,值 0 对枚举的描述性不是很强。为了修复它并避免 CA1008 警告,我再次更改枚举:

enum Gender
{
Unknown = 0,
Male = 1,
Female = 2
}

未初始化的属性现在显示为 Unknown,看起来不错。但我可能引入了另一个问题,即 Unknown 值看起来像一个有效值,可以应用于用户。我也可能会收到关于不处理所有枚举值的警告。假设,我使用的构造函数要求我指定性别和名称以避免未初始化的属性:

public Person(string name, Gender gender)
{
Name = name ?? throw new ArgumentNullException(name);
Gender = gender;
}

当我定义 Unknown 枚举时,我现在可以明确地将性别设置为 Unknown。当然这可以在构造函数中检查,但这只会在运行时发出信号。当 Unknown 值未定义时,调用者只能将其设置为 male 或 female。

解决方法可能是使用可为 null 的性别属性,因此未初始化的值是显式的 null 值(我们不再定义 Unknown 值)。但是使用可空类型会使编程变得更加复杂,所以我不建议这样做。

ObsoleteAttribute 应用于 Unknown 值可能是个好主意。当有人明确使用该值时,它会被标记为警告(在构建时)。

处理未初始化枚举值的正确方法是什么?使用 ObsoleteAttribute 是个好主意还是它有其他缺点?

注意事项:* 虽然过时不是这里的正确语义,但如果使用该值,它是生成警告的唯一(简单)方法。* 在没有默认构造函数的情况下使用 POCO 可能会使序列化复杂化,因此拥有(可序列化的)类而没有它们通常不是一个好主意。

最佳答案

is using the ObsoleteAttribute a good idea?

没有。使用 [Obsolete] 来……等待……将一个过时的成员标记为过时。这是 唯一 [Obsolete] 的正确用法。不要为现有词发明新的含义;这只会造成困惑。

What is the proper way to deal with the uninitialized enumeration values?

这是个错误的问题。退后一步。让我们看看您的问题的大图:

  1. 你决定使用枚举
  2. 你收到一堆警告说你的枚举违反了一些准则,你认为这些准则很重要
  3. 您为遵循指南所做的每一次尝试都会产生一个新问题,并且您认为这些问题很重要。

现在你被困住了,想知道该怎么做。

您要做的是:返回步骤 1 到 3 并做出不同的决定

假设我们重新审视决策 3。您已经确定了每种解决方案的一系列优缺点。确定其中一个利大于弊,并接受它。

假设我们重新审视决定 2。您违反了一系列准则。指南不是规则。您可以确定指南对您的场景来说是错误的建议,记录您故意违反它们的事实以及原因,取消警告,然后继续。

假设我们重新审视决定 1。您是决定性别最好用枚举表示的人,从那以后这个决定似乎给您带来了相当大的痛苦。所以拒绝那个决定:

abstract class Gender : 
whatever interfaces you need for serialization and so on
{
private Gender() { } // prevent subclassing
private class MaleGender : Gender
{
// Serialization code for male gender
}
public static readonly Gender Male = new MaleGender();
// now do it all again for FemaleGender
}

我们得到了什么?我们有 Gender.MaleGender.Female 和以前一样,它们和以前一样是可序列化的,以及 Gender 类型的任何值是男性、女性或 null。不喜欢空值?抛出一个异常,就像你得到一个空字符串作为人名一样。想要添加更多性别,例如“未知”或“非二元性”或其他什么?添加新的子类型和静态字段。

您不会被迫使用枚举。如果满足枚举准则让您烦恼,请停止使用枚举。

关于c# - 如何在 C# 中处理枚举 0(CA1008 讨论),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54561566/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com