I have an enum and i want to \"hide\" one of its values (as i add it for future support). The code is written in C#.
public enum MyEnum
{
ValueA = 0,
Are you using the "hidden" value internally? If not:
public enum MyEnum
{
ValueA = 0,
ValueB = 1,
//TODO: Reserved
}
You gain nothing by defining an unused variable.
This is not possible in C#. All enum values are accessible if the Enum
itself is accessible.
The only way you could simulate accomplishing this is by using a less accessible static field that used an integer value not already used in the Enum
.
public enum MyEnum {
ValueA = 0;
ValueB = 1;
}
internal static class MyEnumEx {
internal static MyEnum Reserved = (MyEnum)42;
}
I'm curious though as to why you would want to do this. No matter what you do users can still provide the Reserved
value. All that needs to be done is to cast an int
of the appropriate value to the MyEnum
type.
// Code that shouldn't access Reserve
MyEnum reserved = (MyEnum)42; // Woot!
I had a similar problem with enum Flags, but the solution I used should work without the Flags attribute.
You can create two enum types, one for the reserved values and the other for the publicly usable values. You can use HasFlag with the reserved type without casting, but assignment requires casting.
[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;
if you want to hide from intellisense or PropertyGrid enumerated members, you can apply:
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
and
[System.ComponentModel.Browsable(false)]
Example:
public enum MyEnum
{
A,
B,
[System.ComponentModel.Browsable(false)]
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
C
}
C is not visible
You can achieve something like this by using your own custom type instead of 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");
}
You could even further emulate the behavior of enum
values by, for example, overloading the explicit
operators to convert to/from MyEnum
objects to int
values (took JaredPar's suggestion to use this rather than implicit
):
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;
}
one way you can do this set the value of this variable null
.
so when ever its called from enum
it'll b null. in short user can't access its value.
public enum MyEnum
{
ValueA = 0,
ValueB = 1,
Reserved.None
}