簡體   English   中英

枚舉值隱藏在 C# 中

[英]Enum value as hidden in C#

我有一個枚舉,我想“隱藏”它的一個值(因為我添加了它以供將來支持)。 代碼是用 C# 編寫的。

public enum MyEnum
{
   ValueA = 0,

   ValueB = 1,

   Reserved
}

我不想讓使用此代碼的人使用此值 (MyEnum.Reserved)。 任何的想法? TIA

您可以使用 'Obsolete' 屬性 - 語義上不正確,但它會做你想做的事:

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

任何嘗試使用Foo.Reserved項進行編譯的Foo.Reserved都會收到錯誤消息

如果您不想顯示它,請不要包含它:

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

    // ...
}

因此,只需稍后在需要時添加您的值,然后修改您的方法以接受它。

這在 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!

如果你想隱藏 intellisense 或 PropertyGrid 枚舉成員,你可以申請:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]

[System.ComponentModel.Browsable(false)]

例子:

  public enum MyEnum
  {
     A,

     B,
     [System.ComponentModel.Browsable(false)]
     [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
     C
  }

C 不可見

您可以通過使用自己的自定義類型而不是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對象轉換為/從MyEnum對象轉換為int值(采用 JaredPar 的建議使用 this 而不是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;
}

您是否在內部使用“隱藏”值? 如果不:

public enum MyEnum
{
   ValueA = 0,
   ValueB = 1,
   //TODO: Reserved
}

定義一個未使用的變量你一無所獲。

一種方法可以設置此變量的null 所以當它從enum調用時,它會為空。 簡而言之,用戶無法訪問其值。

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

   Reserved.None
}

你不能隱藏它,但你可以添加一個注釋,這個值此時沒有任何影響。 否則只需刪除它並在添加支持時添加它,只要原始值不更改,這不應破壞任何其他依賴於它的代碼。

我對 enum 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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM