Добавление C # enum - PullRequest
       48

Добавление C # enum

4 голосов
/ 09 февраля 2010

привет, у меня есть следующее перечисление:

    public enum LegalShipTypes : byte
    {
        Frigate = 1,
        Cruiser = 2,
        Destroyer = 3,
        Submarine = 4,
        AircraftCarrier = 5
    }

Мне было интересно, есть ли способ каким-либо образом получить общее значение enum. например, это приведет к (1 + 2 + 3 + 4 + 5) = 15.

спасибо.

Ответы [ 7 ]

8 голосов
/ 09 февраля 2010

Если вы можете редактировать перечисление и вам нужна его сумма во многих местах, вы можете поместить ее в само перечисление:

public enum LegalShipTypes : byte {
  Frigate = 1,
  Cruiser = 2,
  Destroyer = 3,
  Submarine = 4,
  AircraftCarrier = 5,
  All = Frigate + Cruiser + Destroyer + Submarine + AircraftCarrier
} 

Это имеет больше смысла в перечислении флагов, хотя:

[Flags]
public enum LegalShipTypes : byte {
  Frigate = 1,
  Cruiser = 2,
  Destroyer = 4,
  Submarine = 8,
  AircraftCarrier = 16,
  All = Frigate | Cruiser | Destroyer | Submarine | AircraftCarrier
} 

Или вы можете просто использовать это:

Enum.GetValues(typeof(LegalShipTypes)).Cast<byte>().Sum(x=>x)

, который возвращает decimal.

Но это более общий способ сделать это (работает независимо от базового типа перечисления):

public decimal Sum(Type enumType) {
  return Enum
    .GetValues(enumType)
    .Cast<object>()
    .Sum(x => (decimal)Convert.ChangeType(x, typeof(decimal)));
}
6 голосов
/ 09 февраля 2010

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

Перечисления предназначены для очень простых типов безопасных представлений состояния. Если вы просто используете константы, то можете присвоить значение неправильным константам. Это предотвращает назначение неправильного типа константы полю. Например, если у вас есть что-то, что ожидает DayOfWeek, вы не можете назначить значение FileAccess, даже если они обе являются константами одного и того же базового типа.

DayOfWeek day = FileAccess.Write; // doesn't work

Если вам нужен этот тип безопасности и , вам не нужно, чтобы ваш enum демонстрировал какой-либо другой тип поведения, тогда используйте enum. Если вы заинтересованы в том, чтобы ваш enum делал и другие вещи (например, перечисление, математические операции и т. Д.), Тогда вам следует подумать об использовании классов. Смотрите мой пример ниже.

public class LegalShipTypes
{
    private readonly byte _numericValue;
    private readonly string _text;

    private LegalShipTypes(byte numericValue, string text)
    {
        _numericValue = numericValue;
        _text = text;
    }

    public byte Value { get { return _numericValue; } }
    public string Text { get { return _text; } }

    public static IEnumerable<LegalShipTypes> All
    {
        get
        {
            return new[] { Frigate, Cruiser, Destroyer, Submarine, AircraftCarrier };
        }
    }

    public static readonly LegalShipTypes Frigate = new LegalShipTypes(1, "Frigate");
    public static readonly LegalShipTypes Cruiser = new LegalShipTypes(2, "Cruiser");
    public static readonly LegalShipTypes Destroyer = new LegalShipTypes(3, "Destroyer");
    public static readonly LegalShipTypes Submarine = new LegalShipTypes(4, "Submarine");
    public static readonly LegalShipTypes AircraftCarrier = new LegalShipTypes(5, "Aircraft Carrier");
}

Теперь вы можете использовать его безопасным способом, например так:

public class Fleet
{
    private readonly List<LegalShipTypes> _ships;

    public Fleet()
    {
        _ships = new List<LegalShipTypes>();
    }

    public LegalShipTypes Flagship { get; set; }
    public ICollection<LegalShipTypes> Ships { get { return _ships; } }
}

....

var fleet = new Fleet();
fleet.FlagShip = LegalShipTypes.AircraftCarrier;
var iDoNotKnowWhyYouWouldNeedThisBut = LegalShipTypes.All.Sum(ship => ship.Value);
Console.WriteLine("The flagship is a(n) \"{0}\".", fleet.FlagShip.Text);
if (fleet.FlagShip == LegalShipTypes.AircraftCarrier) // this will work because it's a reference comparison
    Console.WriteLine("This should be true");

Как видите, у вас все еще есть безопасность типов, но гораздо больше гибкости. Это больше кода, но вы не обнаружите, что работаете против ограничений enum. Повторюсь, enum должен быть простым. Это должно быть просто. Если ваши потребности просты, не стесняйтесь использовать его. Если ваши потребности сложнее, вам не стыдно использовать старомодное объектно-ориентированное программирование для решения вашей проблемы.

EDIT

В свете вашего последнего комментария, что байтовые значения представляют количество колышков, я настоятельно рекомендую вам не использовать перечисления для решения вашей проблемы. Вы (по иронии судьбы) пытаетесь вставить круглую колышек в квадратное отверстие.

5 голосов
/ 09 февраля 2010

Попробуйте следующее, предполагая, что это перечисление, которое наследуется от System.Int32 (это значение по умолчанию).

public int Sum(Type enumType) {
  return Enum.GetValues(enumType).Cast<int>().Sum();
}

РЕДАКТИРОВАТЬ не заметил, что вопрос ОП наследуется от byte. Вот версия, которая работает с byte

public int Sum(Type enumType) {
  return Enum.GetValues(enumType).Cast<byte>().Select(x => (int)x).Sum();
}
1 голос
/ 09 февраля 2010

См. Принятый ответ на этот похожий вопрос:

Как мне перечислить перечисление?

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

0 голосов
/ 18 декабря 2012
 public enum LegalShipTypes : byte
    {
        Frigate = 1,
        Cruiser = 2,
        Destroyer = 3,
        Submarine = 4,
        AircraftCarrier = 5
    }
    class Program
    {
        static void Main()
        {
            byte sum = 0;
            foreach (byte item in Enum.GetValues(typeof(LegalShipTypes)))
            {
                sum += (byte)(object)item;
            }

            Console.WriteLine(sum);
        }
    }
0 голосов
/ 09 февраля 2010

Если вы хотите суммировать значения перечислителя, не лучше ли использовать помеченный перечислитель?

0 голосов
/ 09 февраля 2010

Общая версия ответа ДжаредПара с исправлением Люка:

public int Sum<T>(Type enumType) {
    return Enum.GetValues(enumType).Cast<T>().Sum();
}

Позвонить по номеру:

Sum<byte>(typeof(LegalShipTypes));

EDIT: Ну, поцарапайте эту идею. Я полагаю:

public int Sum(Type enumType) {
    return Enum.GetValues(enumType).Cast<byte>().Sum();
}

это ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...