开发者

Enum value as hidden in C#

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,

   ValueB = 1,

   Reserved
}
开发者_C百科

I don't want to allow peoples who use this code to use this values (MyEnum.Reserved). Any idea? TIA


You could use the 'Obsolete' attribute - semantically incorrect, but it will do what you want:

public enum MyEnum 
{ 
  ValueA = 0, 
  ValueB = 1, 
  [Obsolete("Do not use this", true)]
  Reserved 
}

Anyone who tries to compile using the Foo.Reserved item will get an error


If you don't want to show it, then don't include it:

public enum MyEnum
{
    ValueA = 0,
    ValueB = 1,
}

Note that a user of this enum can still assign any integer value to a variable declared as MyEnum:

MyEnum e = (MyEnum)2;  // works!

This means that a method that accepts an enum should always validate this input before using it:

void DoIt(MyEnum e)
{
    if (e != MyEnum.ValueA && e != MyEnum.ValueB)
    {
        throw new ArgumentException();
    }

    // ...
}

So, just add your value later, when you need it, and modify your methods to accept it then.


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!


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;
}


You can't hide it, but you can add a comment that this value doesn't have any effect at this moment. Otherwise just remove it and add it if you add the support, this shouldn't break any other code dependent on it, as long as the original values don't change.


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.


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
}


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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜