Енум "Спадщина"


391

У мене є перелік у просторі імен низького рівня. Я хотів би надати клас або enum у просторі імен середнього рівня, які "успадковують" enum низького рівня.

namespace low
{
   public enum base
   {
      x, y, z
   }
}

namespace mid
{
   public enum consume : low.base
   {
   }
}

Я сподіваюся, що це можливо, або, можливо, якийсь клас, який може зайняти місце споживання enum, який забезпечить шар абстракції для enum, але все ж дозволити екземпляру цього класу отримати доступ до enum.

Думки?

EDIT: Однією з причин того, що я не просто переключив це на конкурси в класах, є те, що перелік низького рівня потрібен службі, яку я повинен споживати. Мені дали WSDL та XSD, які визначають структуру як перерахунок. Службу неможливо змінити.


Відповіді:


462

Це неможливо. Енуми не можуть успадковувати інші переписки. Насправді всі переживачі повинні наслідувати насправді System.Enum. C # дозволяє синтаксису змінювати базове подання значень enum, яке виглядає як спадкування, але насправді вони все ж успадковуються з System.enum.

Детальні відомості див. У розділі 8.5.2 специфікації CLI . Відповідна інформація від специфікації

  • Усі переліки повинні випливати з цього System.Enum
  • Через вищезазначене всі перерахунки є типовими типами і, отже, запечатані

2
І всі типи значень походять від System.ValueType
Raz Megrelidze

4
Повинен відзначити , що відповідь @Seven «сек є законним обхідним шляхом: stackoverflow.com/a/4042826/538387
Tohid

але відповідь @ Стівена не можна використовувати в switchситуації.
zionpi

@zionpi так, але зауважте, що (я вважаю) стандартний перемикач компілюється в той самий код ІЛ як повний, якщо, інакше, якщо інший блок би: який, на мою думку, в кращому випадку має кращий синтаксис. Ви втрачаєте здатність resharper / VS до автоматичного заповнення всіх заяв справи, але я думаю, це ще не кінець світу. Це особисті переваги, але я не прихильник заяви про перемикання.
MemeDeveloper

165

Ви можете досягти того, що хочете, за допомогою занять:

public class Base
{
    public const int A = 1;
    public const int B = 2;
    public const int C = 3;
}
public class Consume : Base
{
    public const int D = 4;
    public const int E = 5;
}

Тепер ви можете використовувати ці класи аналогічно, як коли вони були переписками:

int i = Consume.B;

Оновлення (після оновлення запитання):

Якщо ви присвоїте ті самі значення int константам, що визначені в існуючій enum, то ви можете переходити між enum і константами, наприклад:

public enum SomeEnum // this is the existing enum (from WSDL)
{
    A = 1,
    B = 2,
    ...
}
public class Base
{
    public const int A = (int)SomeEnum.A;
    //...
}
public class Consume : Base
{
    public const int D = 4;
    public const int E = 5;
}

// where you have to use the enum, use a cast:
SomeEnum e = (SomeEnum)Consume.B;

8
Як тоді ви перераховуєте поля в цьому класі? Для мене важлива поведінка перерахунків:Enum.GetValues(typeof(MyEnum)
Майк де Клерк

1
Ви можете використовувати роздуми: void Test() { foreach (System.Reflection.PropertyInfo pi in typeof(Consume).GetProperties()) { Console.WriteLine(pi.Name); } }
mnieto

2
Вам потрібно переконатися, що збирання властивостей з відображенням ігнорує успадковані властивості Об'єкта.
Роберт

Рефлексія дуже негарна для цього завдання.
dylanh724

1
Не потрібно використовувати Reflection, реалізація на codeproject.com/Articles/20805/Enhancing-C-Enums - це хороший спосіб зробити це, оскільки об’єкти створюються, вони додаються до списку, і цей список можна використовувати повернути список типів об'єктів. Коли ви змішуєте його зі спадщиною, вам доведеться переконатися, що ви використовуєте правильний список для класів успадкування.
PBo

112

Коротка відповідь - ні. Ви можете трохи пограти, якщо хочете:

Ви завжди можете зробити щось подібне:

private enum Base
{
    A,
    B,
    C
}

private enum Consume
{
    A = Base.A,
    B = Base.B,
    C = Base.C,
    D,
    E
}

Але це не дуже добре, тому що Base.A! = Споживати

Ви завжди можете зробити щось подібне, хоча:

public static class Extensions
{
    public static T As<T>(this Consume c) where T : struct
    {
        return (T)System.Enum.Parse(typeof(T), c.ToString(), false);
    }
}

Для того, щоб перетинати Базу та Споживати ...

Ви також можете виводити значення переліків як int і порівнювати їх як int замість enum, але такий вид також є відстійним.

Повернення методу розширення повинно вводити тип T.


4
Я це копаю, чоловіче. Використовував цю концепцію, щоб передати деякі перерахунки з мого ORM на мій публічний інтерфейс (для тих, хто не має посилання на ORM).
Тип об’єкта

5
Можна порівняти з роботою:Base.A == (Base)Consume.A
Кресимир

1
Використовуйте (десяткове) Base.A == (десятковий) Consume.A. Причина: Ось як працює комбінування біта прапор / маска (наприклад, в Enum.IsDefined msdn.microsoft.com/en-us/library/… ). Таким чином, enum може бути встановлений на ціле число, не визначене в enum. Споживайте тест = 123456;
TamusJRoyce

3
@TamusJRoyce десятковий? intмав би набагато більше сенсу. Коли б у перерахунку була дробова частина!?!?!
ЕрікЕ

Принаймні, це гарантує, що відповідні константи перерахунків мають однакове ціле значення. Зрештою, перерахунки - це лише сукупність цілих констант. C # не встановлює, що призначені значення є константами vaild enum, тобто перерахунки не є безпечними у строгому значенні.
Олів'є Якот-Дескомб

98

Вищевикладені рішення з використанням класів з int-константами не мають безпеки типу. Тобто ви могли б винайти нові значення, фактично не визначені в класі. Крім того, неможливо, наприклад, написати метод, який бере один із цих класів як вхідний.

Вам потрібно було б написати

public void DoSomethingMeaningFull(int consumeValue) ...

Однак є рішення на основі класів старих часів Java, коли не було доступних переліків. Це забезпечує майже переживаючу поведінку. Єдине застереження полягає в тому, що ці константи не можна використовувати в операторі switch.

public class MyBaseEnum
{
    public static readonly MyBaseEnum A = new MyBaseEnum( 1 );
    public static readonly MyBaseEnum B = new MyBaseEnum( 2 );
    public static readonly MyBaseEnum C = new MyBaseEnum( 3 );

    public int InternalValue { get; protected set; }

    protected MyBaseEnum( int internalValue )
    {
        this.InternalValue = internalValue;
    }
}

public class MyEnum : MyBaseEnum
{
    public static readonly MyEnum D = new MyEnum( 4 );
    public static readonly MyEnum E = new MyEnum( 5 );

    protected MyEnum( int internalValue ) : base( internalValue )
    {
        // Nothing
    }
}

[TestMethod]
public void EnumTest()
{
    this.DoSomethingMeaningful( MyEnum.A );
}

private void DoSomethingMeaningful( MyBaseEnum enumValue )
{
    // ...
    if( enumValue == MyEnum.A ) { /* ... */ }
    else if (enumValue == MyEnum.B) { /* ... */ }
    // ...
}

7
Я думаю, що це правильна відповідь. Ви не можете мати спадщину для Enum, але це може дозволити вам керувати ним!
робоб

11
Приємно і чисто. +1. Лише натяк, вам дійсно не потрібно значення int.
Ігнасіо Солер Гарсія

1
Я ніколи не думав про перерахування, як ніби ви можете сказати FileOpenMode.Read> FileOpenMode.Write. Якщо це так, то вам потрібен int або ще краще IEqualityComparer для цього перерахунку. З повагою
Ігнасіо Солер Гарсія

3
@binki, використовуючи random object's, зробить значення різними для кожної інстанції збірки, тому вони не можуть бути серіалізовані.
ivan_pozdeev

2
Але це не дозволяє вам "увімкнути" MyEnum, чи не так? Я маю на увазі, що саме тому я використовую переписки ...
MemphiZ

13

Ігноруючи той факт, що основа є зарезервованим словом, ви не можете зробити спадкування перерахунків.

Найкраще, що ви могли зробити, - це щось таке:

public enum Baseenum
{
   x, y, z
}

public enum Consume
{
   x = Baseenum.x,
   y = Baseenum.y,
   z = Baseenum.z
}

public void Test()
{
   Baseenum a = Baseenum.x;
   Consume newA = (Consume) a;

   if ((Int32) a == (Int32) newA)
   {
   MessageBox.Show(newA.ToString());
   }
}

Оскільки вони всі однакові базового типу (тобто: int), ви можете призначити значення з екземпляра одного типу іншому, який є атрибутом. Не ідеально, але це працює.


2
База зарезервована, але Бази немає
erikkallen

2
Він має на увазі використання операційного про базу в якості імені перерахувань, це просто приклад , назву я впевнений
John Rasch

Те саме, що відповідь Генісіо.
nawfal

6

Я знаю, що ця відповідь запізнюється, але я закінчив це:

public class BaseAnimal : IEquatable<BaseAnimal>
{
    public string Name { private set; get; }
    public int Value { private set; get; }

    public BaseAnimal(int value, String name)
    {
        this.Name = name;
        this.Value = value;
    }

    public override String ToString()
    {
        return Name;
    }

    public bool Equals(BaseAnimal other)
    {
        return other.Name == this.Name && other.Value == this.Value;
    }
}

public class AnimalType : BaseAnimal
{
    public static readonly BaseAnimal Invertebrate = new BaseAnimal(1, "Invertebrate");

    public static readonly BaseAnimal Amphibians = new BaseAnimal(2, "Amphibians");

    // etc        
}

public class DogType : AnimalType
{
    public static readonly BaseAnimal Golden_Retriever = new BaseAnimal(3, "Golden_Retriever");

    public static readonly BaseAnimal Great_Dane = new BaseAnimal(4, "Great_Dane");

    // etc        
}

Тоді я можу робити такі речі, як:

public void SomeMethod()
{
    var a = AnimalType.Amphibians;
    var b = AnimalType.Amphibians;

    if (a == b)
    {
        // should be equal
    }

    // call method as
    Foo(a);

    // using ifs
    if (a == AnimalType.Amphibians)
    {
    }
    else if (a == AnimalType.Invertebrate)
    {
    }
    else if (a == DogType.Golden_Retriever)
    {
    }
    // etc          
}

public void Foo(BaseAnimal typeOfAnimal)
{
}

2
Магічні числа можна замінити об'єктами відповідно до stackoverflow.com/questions/757684/… . Але в цьому конкретному випадку ви можете отримати найкраще з обох світів, використовуючи особливості існуючої біологічної номенклатури, щоб гарантувати унікальність.
ivan_pozdeev

4

Це я і зробив. Що я робив по-іншому, це використовувати те саме ім’я та newключове слово на "споживаючий" enum. Оскільки ім’я enumцього самого, ви можете просто бездумно його використовувати, і це буде правильно. Плюс ви отримаєте інтелігенцію. Вам просто потрібно вручну подбати про те, щоб значення копіювались із бази та зберігали їх синхронізовано. Ви можете допомогти в цьому разом із кодовими коментарями. Це ще одна причина, чому в базі даних при зберіганні enumзначень я завжди зберігаю рядок, а не значення. Тому що якщо ви використовуєте автоматично присвоєні цілі цілі значення, вони можуть змінюватися з часом.

// Base Class for balls 
public class BaseBall
{
    // keep synced with subclasses!
    public enum Sizes
    {
        Small,
        Medium,
        Large
    }
}

public class VolleyBall : BaseBall
{
    // keep synced with base class!
    public new enum Sizes
    {
        Small = BaseBall.Sizes.Small,
        Medium = BaseBall.Sizes.Medium,
        Large = BaseBall.Sizes.Large,
        SmallMedium,
        MediumLarge,
        Ginormous
    }
}

2
Подумайте про встановлення іншого діапазону для нових значень у похідному класі (наприклад SmallMedium = 100,), щоб ви могли зберігати сумісність зі старими версіями свого програмного забезпечення, коли ви додаєте нові значення в базовий клас. Наприклад, додавання Hugeрозміру в базовий enum призначить 4його значення, але 4воно вже прийняте SmallMediumу похідному класі.
Роберто

1
@Roberto, Щоб вирішити це, я ніколи не зберігаю значення перерахунків, а лише імена. І тут потрібно підтримувати їх синхронізацію. Тому для додавання Hugeв базовий клас знадобиться Hugeпідклас ранішеSmallMedium
tddmo

2
BaseBallможливо, тут не найрозумніша назва. Це заплутано. Оскільки бейсбол - це насправді річ. Якщо ви пропустите, що це лише базовий клас для м'яча, це виглядає дуже дивно, що волейбол успадковує фізично менший бейсбол :). Моя пропозиція просто використовуватиBall
Нік Н.

3

Альтернативне рішення

У моїй компанії ми уникаємо "перестрибування проектів", щоб потрапити на незвичайні проекти нижчого рівня. Наприклад, наш рівень презентації / API може посилатися лише на наш доменний рівень, а рівень домену може посилатися лише на рівень даних.

Однак це проблема, коли є переліки, на які потрібно посилатися як у презентаційному, так і в доменному шарах.

Ось рішення, яке ми реалізували (поки що). Це досить гарне рішення і добре працює для нас. Інші відповіді вражали все навколо.

Основна передумова полягає в тому, що переліки не можуть бути успадковані - але класи можуть. Тому...

// In the lower level project (or DLL)...
public abstract class BaseEnums
{
    public enum ImportanceType
    {
        None = 0,
        Success = 1,
        Warning = 2,
        Information = 3,
        Exclamation = 4
    }

    [Flags]
    public enum StatusType : Int32
    {
        None = 0,
        Pending = 1,
        Approved = 2,
        Canceled = 4,
        Accepted = (8 | Approved),
        Rejected = 16,
        Shipped = (32 | Accepted),
        Reconciled = (64 | Shipped)
    }

    public enum Conveyance
    {
        None = 0,
        Feet = 1,
        Automobile = 2,
        Bicycle = 3,
        Motorcycle = 4,
        TukTuk = 5,
        Horse = 6,
        Yak = 7,
        Segue = 8
    }

Потім, щоб "успадкувати" перерахунків в іншому проекті вищого рівня ...

// Class in another project
public sealed class SubEnums: BaseEnums
{
   private SubEnums()
   {}
}

Це має три реальні переваги ...

  1. Визначення перерахунків автоматично однакові в обох проектах - за визначенням.
  2. Будь-які зміни у визначеннях перерахунків автоматично повторюються у другому, не змінюючи другого класу.
  3. Перерахунки базуються на одному і тому ж коді - тому значення легко можна порівняти (з деякими застереженнями).

Для посилання на переліків у першому проекті ви можете використовувати префікс класу: BaseEnums.StatusType.Pending або додати "з використанням статичних BaseEnums;" заява на ваші узі.

У другому проекті, маючи справу з успадкованим класом, я не міг отримати підхід до "використання статичних ..." , тому всі посилання на "успадковані перерахунки" мають бути префіксом для класу, наприклад SubEnums.StatusType.Pending . Якщо хтось придумає спосіб дозволити використовувати " другий статичний" підхід у другому проекті, дайте мені знати.

Я впевнений, що це можна змінити, щоб зробити це ще краще - але це насправді працює, і я використовував такий підхід у робочих проектах.

Будь ласка, голосуйте за це, якщо вам це здається корисним.


2

Я також хотів перевантажити Enums і створив поєднання відповідей "Сімки" на цій сторінці та відповіді "Мерлін Морган-Грем" на дублікат цього повідомлення , а також ще кілька вдосконалень.
Основні переваги мого рішення перед іншими:

  • автоматичне збільшення базового значення int
  • автоматичне називання

Це нестандартне рішення і може бути безпосередньо вставлено у ваш проект. Він розроблений для моїх потреб, тому якщо вам не подобаються деякі його частини, просто замініть їх власним кодом.

По-перше, існує базовий клас CEnum, від якого повинні успадковувати всі користувацькі перераховані користувачі. Він має основний функціонал, схожий на Enumтип .net :

public class CEnum
{
  protected static readonly int msc_iUpdateNames  = int.MinValue;
  protected static int          ms_iAutoValue     = -1;
  protected static List<int>    ms_listiValue     = new List<int>();

  public int Value
  {
    get;
    protected set;
  }

  public string Name
  {
    get;
    protected set;
  }

  protected CEnum ()
  {
    CommonConstructor (-1);
  }

  protected CEnum (int i_iValue)
  {
    CommonConstructor (i_iValue);
  }

  public static string[] GetNames (IList<CEnum> i_listoValue)
  {
    if (i_listoValue == null)
      return null;
    string[] asName = new string[i_listoValue.Count];
    for (int ixCnt = 0; ixCnt < asName.Length; ixCnt++)
      asName[ixCnt] = i_listoValue[ixCnt]?.Name;
    return asName;
  }

  public static CEnum[] GetValues ()
  {
    return new CEnum[0];
  }

  protected virtual void CommonConstructor (int i_iValue)
  {
    if (i_iValue == msc_iUpdateNames)
    {
      UpdateNames (this.GetType ());
      return;
    }
    else if (i_iValue > ms_iAutoValue)
      ms_iAutoValue = i_iValue;
    else
      i_iValue = ++ms_iAutoValue;

    if (ms_listiValue.Contains (i_iValue))
      throw new ArgumentException ("duplicate value " + i_iValue.ToString ());
    Value = i_iValue;
    ms_listiValue.Add (i_iValue);
  }

  private static void UpdateNames (Type i_oType)
  {
    if (i_oType == null)
      return;
    FieldInfo[] aoFieldInfo = i_oType.GetFields (BindingFlags.Public | BindingFlags.Static);

    foreach (FieldInfo oFieldInfo in aoFieldInfo)
    {
      CEnum oEnumResult = oFieldInfo.GetValue (null) as CEnum;
      if (oEnumResult == null)
        continue;
      oEnumResult.Name = oFieldInfo.Name;
    }
  }
}

По-друге, ось два похідні класи Енума. Усі похідні класи потребують деяких основних методів, щоб працювати, як очікувалося. Це завжди один і той же код котла; Я ще не знайшов способу передати його на базовий клас. Код першого рівня успадкування дещо відрізняється від усіх наступних рівнів.

public class CEnumResult : CEnum
{
  private   static List<CEnumResult>  ms_listoValue = new List<CEnumResult>();

  public    static readonly CEnumResult Nothing         = new CEnumResult (  0);
  public    static readonly CEnumResult SUCCESS         = new CEnumResult (  1);
  public    static readonly CEnumResult UserAbort       = new CEnumResult ( 11);
  public    static readonly CEnumResult InProgress      = new CEnumResult (101);
  public    static readonly CEnumResult Pausing         = new CEnumResult (201);
  private   static readonly CEnumResult Dummy           = new CEnumResult (msc_iUpdateNames);

  protected CEnumResult () : base ()
  {
  }

  protected CEnumResult (int i_iValue) : base (i_iValue)
  {
  }

  protected override void CommonConstructor (int i_iValue)
  {
    base.CommonConstructor (i_iValue);

    if (i_iValue == msc_iUpdateNames)
      return;
    if (this.GetType () == System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType)
      ms_listoValue.Add (this);
  }

  public static new CEnumResult[] GetValues ()
  {
    List<CEnumResult> listoValue = new List<CEnumResult> ();
    listoValue.AddRange (ms_listoValue);
    return listoValue.ToArray ();
  }
}

public class CEnumResultClassCommon : CEnumResult
{
  private   static List<CEnumResultClassCommon> ms_listoValue = new List<CEnumResultClassCommon>();

  public    static readonly CEnumResult Error_InternalProgramming           = new CEnumResultClassCommon (1000);

  public    static readonly CEnumResult Error_Initialization                = new CEnumResultClassCommon ();
  public    static readonly CEnumResult Error_ObjectNotInitialized          = new CEnumResultClassCommon ();
  public    static readonly CEnumResult Error_DLLMissing                    = new CEnumResultClassCommon ();
  // ... many more
  private   static readonly CEnumResult Dummy                               = new CEnumResultClassCommon (msc_iUpdateNames);

  protected CEnumResultClassCommon () : base ()
  {
  }

  protected CEnumResultClassCommon (int i_iValue) : base (i_iValue)
  {
  }

  protected override void CommonConstructor (int i_iValue)
  {
    base.CommonConstructor (i_iValue);

    if (i_iValue == msc_iUpdateNames)
      return;
    if (this.GetType () == System.Reflection.MethodBase.GetCurrentMethod ().DeclaringType)
      ms_listoValue.Add (this);
  }

  public static new CEnumResult[] GetValues ()
  {
    List<CEnumResult> listoValue = new List<CEnumResult> (CEnumResult.GetValues ());
    listoValue.AddRange (ms_listoValue);
    return listoValue.ToArray ();
  }
}

Заняття були успішно протестовані з наступним кодом:

private static void Main (string[] args)
{
  CEnumResult oEnumResult = CEnumResultClassCommon.Error_Initialization;
  string sName = oEnumResult.Name;   // sName = "Error_Initialization"

  CEnum[] aoEnumResult = CEnumResultClassCommon.GetValues ();   // aoEnumResult = {testCEnumResult.Program.CEnumResult[9]}
  string[] asEnumNames = CEnum.GetNames (aoEnumResult);
  int ixValue = Array.IndexOf (aoEnumResult, oEnumResult);    // ixValue = 6
}

1

Енуми - це не фактичні класи, навіть якщо вони виглядають так. Всередині них поводяться так само, як і їх базовий тип (за замовчуванням Int32). Тому ви можете це зробити, лише "скопіювавши" окремі значення з одного перерахунку в інший і відкинувши їх до їх цілого числа, щоб порівняти їх для рівності.


1

Енуми не можуть бути похідні від інших переліків, а лише з int, uint, short, ushort, long, ulong, byte та sbyte.

Як сказав Паскаль, ви можете використовувати інші значення або константи enum, щоб ініціалізувати значення enum, але це стосується цього.


8
Це трохи помилково через синтаксис c #, але enum не може наслідувати нас від int, uint тощо. Під кришкою вони все ще успадковують від System.Enum. Просто член, який представляє enum, набирається до int, uint тощо.
JaredPar

@JaredPar. Коли enum походить від uint, це означає, що значення є всі uint і т.д. За замовчуванням enum успадковує int. (Погляньте на специфікацію C #, перерахуйте SomeEnum: uint {...} насправді працює.)
Jeroen Landheer

4
Насправді ні. Він успадковує System.enum. Як було розміщено раніше і частіше тут, те, що, на вашу думку, є спадщиною, - це лише двомовна двозначність у csharp.
TomTom

1

інше можливе рішення:

public enum @base
{
    x,
    y,
    z
}

public enum consume
{
    x = @base.x,
    y = @base.y,
    z = @base.z,

    a,b,c
}

// TODO: Add a unit-test to check that if @base and consume are aligned

HTH


1

Це неможливо (як @JaredPar вже згадувалося). Намагатися використовувати логіку, щоб обійти це - погана практика. Якщо у вас є base classтакий enum, ви повинні перелічити все можливеenum-values там, і реалізація класу повинна працювати зі значеннями, які він знає.

Наприклад, якщо у вас базовий клас BaseCatalog, він має enum ProductFormats( Digital, Physical). Тоді ви можете мати MusicCatalogабо BookCatalogщо може містить як Digitalі Physicalпродукти, але якщо клас ClothingCatalog, він повинен містить тільки Physicalпродукти.


1

Я розумію, що я трохи спізнююся на цю вечірку, але ось два мої центи.

Нам усім зрозуміло, що успадкування Enum не підтримується рамками. У цій темі було запропоновано кілька дуже цікавих способів вирішення, але жоден із них не відчував себе таким, як я шукав, тому я сам був у цьому.

Представляємо: ObjectEnum

Ви можете перевірити код та документацію тут: https://github.com/dimi3tron/ObjectEnum .

І пакет тут: https://www.nuget.org/packages/ObjectEnum

Або просто встановіть його: Install-Package ObjectEnum

Коротко, ObjectEnum<TEnum> діє як обгортка для будь-якого перерахунку. Перезаписуючи GetDefinedValues ​​() у підкласах, можна вказати, які значення перерахунків є дійсними для цього конкретного класу.

Додано ряд перевантажень оператора, щоб зробити ObjectEnum<TEnum> екземпляр вести себе так, ніби це екземпляр базового перерахунку, маючи на увазі визначені обмеження значення. Це означає, що ви можете легко порівняти екземпляр зі значенням int або enum і, таким чином, використовувати його у випадку комутатора або будь-якому іншому умовному.

Я хотів би посилатися на згадку про реквізит github вище для прикладів та додаткової інформації.

Я сподіваюся, що Ви вважаєте це корисним. Не соромтесь коментувати або відкривати питання на Github для подальших думок чи коментарів.

Ось кілька коротких прикладів того, що можна зробити з ObjectEnum<TEnum>:

var sunday = new WorkDay(DayOfWeek.Sunday); //throws exception
var monday = new WorkDay(DayOfWeek.Monday); //works fine
var label = $"{monday} is day {(int)monday}." //produces: "Monday is day 1."
var mondayIsAlwaysMonday = monday == DayOfWeek.Monday; //true, sorry...

var friday = new WorkDay(DayOfWeek.Friday);

switch((DayOfWeek)friday){
    case DayOfWeek.Monday:
        //do something monday related
        break;
        /*...*/
    case DayOfWeek.Friday:
        //do something friday related
        break;
}

-8

Ви можете виконувати спадщину в перерахунку, однак вона обмежується лише такими типами. int, uint, byte, sbyte, short, ushort, long, ulong

Напр

public enum Car:int{
Toyota,
Benz,
}

2
Я думаю, що ОП просила успадкувати один перерахунок від іншого, а не лише від базового числового типу (що всі перерахунки роблять у C #, неявно чи явно).
reirab
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.