我有一个枚举,我想“隐藏”其中一个值(因为我将其添加以供将来支持)。 代码用C#编写。
public enum MyEnum
{
ValueA = 0,
ValueB = 1,
Reserved
}
我不想允许使用此代码的人使用此值(MyEnum.Reserved)。 任何的想法? TIA
答案 0 :(得分:9)
你可以使用'过时'属性 - 在语义上不正确,但它会做你想要的:
public enum MyEnum
{
ValueA = 0,
ValueB = 1,
[Obsolete("Do not use this", true)]
Reserved
}
任何尝试使用Foo.Reserved
项目进行编译的人都会收到错误
答案 1 :(得分:5)
如果您不想展示它,请不要包含它:
public enum MyEnum
{
ValueA = 0,
ValueB = 1,
}
请注意,此枚举的用户仍然可以将任何整数值分配给声明为MyEnum的变量:
MyEnum e = (MyEnum)2; // works!
这意味着接受枚举的方法应始终在使用之前验证此输入:
void DoIt(MyEnum e)
{
if (e != MyEnum.ValueA && e != MyEnum.ValueB)
{
throw new ArgumentException();
}
// ...
}
因此,只需稍后在需要时添加您的值,然后修改您的方法以接受它。
答案 2 :(得分:2)
这在C#中是不可能的。如果可以访问Enum
本身,则可以访问所有枚举值。
您可以模拟完成此操作的唯一方法是使用不太容易访问的静态字段,该字段使用Enum
中尚未使用的整数值。
public enum MyEnum {
ValueA = 0;
ValueB = 1;
}
internal static class MyEnumEx {
internal static MyEnum Reserved = (MyEnum)42;
}
我很好奇你为什么要这样做。无论您做什么,用户仍然可以提供Reserved
值。所有需要做的就是将int
适当的值转换为MyEnum
类型。
// Code that shouldn't access Reserve
MyEnum reserved = (MyEnum)42; // Woot!
答案 3 :(得分:2)
您可以使用自己的自定义类型而不是enum
来实现 这样的内容:
// This type works pretty much the same way an enum works;
// each specific value can be cast to/from an int, and each has
// a specific name that is returned on calling ToString().
public sealed class MyEnum
{
private readonly int _value;
private readonly string _name;
// private constructor -- ensure that the static members you define below
// are the only MyEnum instances accessible from any outside code
private MyEnum(int value, string name)
{
_value = value;
_name = name;
}
// no need to override Equals or GetHashCode, believe it or not --
// one instance per value means we can use reference equality and
// that should be just fine
public override string ToString()
{
return _name;
}
// provide direct access only to these members
public static readonly MyEnum ValueA = new MyEnum(0, "ValueA");
public static readonly MyEnum ValueB = new MyEnum(1, "ValueB");
// this member is only available to you within the current assembly
internal static readonly MyEnum Reserved = new MyEnum(-1, "Reserved");
}
您甚至可以进一步模拟enum
值的行为,例如,重载explicit
运算符以转换为MyEnum
对象/从int
对象转换为implicit
值JaredPar建议使用此而不是public static explicit operator MyEnum(int value)
{
switch (value)
{
case 0:
return ValueA;
case 1:
return ValueB;
default:
throw new InvalidCastException();
}
}
public static explicit operator int(MyEnum value)
{
return value._value;
}
):
{{1}}
答案 4 :(得分:0)
您无法隐藏它,但您可以添加一个注释,此值此时没有任何效果。否则只需删除它并在添加支持时添加它,这不应该破坏任何其他依赖它的代码,只要原始值不会改变。
答案 5 :(得分:0)
您使用的是"隐藏"价值内部?如果不是:
public enum MyEnum
{
ValueA = 0,
ValueB = 1,
//TODO: Reserved
}
通过定义未使用的变量,你什么也得不到。
答案 6 :(得分:0)
枚举Flags也有类似的问题,但是我使用的解决方案应该在没有Flags属性的情况下工作。
您可以创建两种枚举类型,一种用于保留值,另一种用于可公开使用的值。您可以将HasFlag与保留类型一起使用,而无需强制转换,但是分配需要强制转换。
[Flags]
public enum MyEnumReserved {
Income = 1,
Expense = 2,
Discretionary = 4,
Critical = 8
}
[Flags]
public enum MyEnum {
Income = MyEnumReserved.Income,
DiscretionaryExpense = MyEnumReserved.Expense | MyEnumReserved.Discretionary,
CriticalExpense = MyEnumReserved.Expense | MyEnumReserved.Critical
}
bool IsIncome(MyEnum val) => val.HasFlag(MyEnumReserved.Income);
...
MyEnum foo = (MyEnum)MyEnumReserved.Expense | (MyEnum)MyEnumReserved.Discretionary;