Перечислимое “Наследование”

Это не немедленная помощь, но создание массивов с большими размерами (через longs) - это предлагаемое изменение языка для Java 7. Ознакомьтесь с предложениями по проектной монете для получения дополнительной информации

367
задан CodeMonkey1313 16 April 2009 в 20:04
поделиться

7 ответов

Это невозможно. Перечисления не могут наследоваться от других перечислений. Фактически все перечисления должны наследоваться от System.Enum . C # позволяет синтаксису изменять базовое представление значений перечисления, которое выглядит как наследование, но в действительности они все еще наследуются от System.enum.

См. Подробности в разделе 8.5.2 спецификации CLI , Соответствующая информация из спецификации

  • Все перечисления должны быть получены из System.Enum
  • Из-за вышеизложенного все перечисления являются типами значений и, следовательно, запечатаны
446
ответ дан 23 November 2019 в 00:06
поделиться

Краткий ответ - нет. Вы можете немного поиграть, если хотите:

Вы всегда можете сделать что-то вроде этого:

private enum Base
{
    A,
    B,
    C
}

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

Но, это не очень хорошо работает, потому что Base.A! = Consume.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);
    }
}

Для того, чтобы перейти между Base и Consume ...

Вы могли бы также привести значения перечислений как целые числа и сравнить их как целые числа вместо перечислений, но этот тип также отстой .

Возвращаемым методом расширения должен быть приведен тип cast типа.

108
ответ дан 23 November 2019 в 00:06
поделиться

Игнорируя тот факт, что base является зарезервированным словом, вы не можете делать наследование enum.

Лучшее, что вы могли do выглядит примерно так:

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), вы можете присвоить значение из экземпляра одного типа другому, который был приведен. Не идеально, но это работает.

13
ответ дан 23 November 2019 в 00:06
поделиться

Перечисления не являются реальными классами, даже если они выглядят так. Внутренне они обрабатываются так же, как и их базовый тип (по умолчанию Int32). Следовательно, вы можете сделать это только путем «копирования» отдельных значений из одного перечисления в другое и приведения их к их целому числу, чтобы сравнить их на равенство.

1
ответ дан 23 November 2019 в 00:06
поделиться

Перечисления не могут быть получены из других перечислений, но только из int, uint, short, ushort, long, ulong, byte и сбайт.

Как сказал Паскаль, вы можете использовать другие значения или константы перечисления для инициализации значения перечисления, но это все.

1
ответ дан 23 November 2019 в 00:06
поделиться

Вы можете достичь того, что вы хотите с классами:

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, которые определены в существующем перечислении, вы можете привести между перечислением и константами, например:

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;
160
ответ дан 23 November 2019 в 00:06
поделиться

Я понимаю, что немного опаздываю этой стороне, но здесь - свои два цента.

Мы все ясны, что Перечислимое наследование не поддерживается платформой. Некоторые очень интересные обходные решения были предложены в этом потоке, но ни один из них не чувствовал вполне как то, что я искал, таким образом, я делал попытку его сам.

Представление: ObjectEnum

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

Или установка пакет: Install-Package ObjectEnum -Version 1.0.0-alpha1

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

Много перегрузок оператора были добавлены для создания ObjectEnum<TEnum>, экземпляр ведет себя, как будто это был экземпляр базового перечисления, имея в виду определенные ограничения значения. Это означает, что можно легко сравнить экземпляр с интервалом или перечислением значений, и таким образом использовать его в случае переключателя или любом другом условном выражении.

я хотел бы обратиться к GitHub repo, упоминают выше для примеров и дальнейшей информации

, я надеюсь, что Вы находите это полезным. Не стесняйтесь комментировать или открывать проблему о 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;
}
0
ответ дан 23 November 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: