Значения перечислений, установленные на разные номера / сброс значений перечисления - PullRequest
0 голосов
/ 11 сентября 2011

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

У меня есть перечисление для разных нот:

public enum NoteValue
{
    A = 0,
    Asharp = 1,
    B = 2,
    C = 3,
    Csharp = 4,
    D = 5,
    Dsharp = 6,
    E = 7,
    F = 8,
    Fsharp = 9,
    G = 10,
    Gsharp = 11
}

Iзатем есть метод, который устанавливает каждую ноту

        public void setNotes(NoteValue startingNote)
        {
        //Creates an array of notes the size that is specified
        theNote = new Note[(numberOfNotes)];

        //Sets the notes
        theNote[0] = new Note(startingNote);
        theNote[1] = new Note((startingNote + step[1]));
        theNote[2] = new Note((startingNote + step[2] + step[1]));
        theNote[3] = new Note((startingNote + step[3] + step[2] + step[1]));
        theNote[4] = new Note((startingNote + step[4] + step[3] + step[2] + step[1]));
        theNote[5] = new Note((startingNote + step[5] + step[4] + step[3] + step[2] + step[1]));
        theNote[6] = new Note((startingNote - step[7]));

        Console.WriteLine("{0} \n{1} \n{2} \n{3} \n{4} \n{5} \n{6}",
            theNote[0].value, theNote[1].value, theNote[2].value, theNote[3].value,
            theNote[4].value, theNote[5].value, theNote[6].value);
    }

Проблема, с которой я сталкиваюсь, заключается в том, что если она пойдет, я начну с G (в моем перечислении 10), он просто начнет печатать числа после G #.Могу ли я сделать так, чтобы он возвращался к 0 после 11, а не просто продолжал?

Я получу что-то вроде этого (для основного масштаба):

G 12 1415 17 19

вместо

GABCDEF #

Есть ли способ исправить это?Спасибо.

Ответы [ 2 ]

4 голосов
/ 11 сентября 2011

Перечисления в том виде, как они определены в C #, в основном являются «строго типизированными» оболочками для целочисленных типов (целых чисел).

Если вы хотите использовать такое поведение для целочисленного переноса, общее решение - использовать оператор по модулю (%):

int note = 12;
var correctlyWrappedNote = note % 12; // will equal 0

Это логически эквивалентно взятию остатка после деления на 12.

После этого вы сможете вернуть его к вашему типу NoteValue:

var actualNote = (NoteValue)correctlyWrappedNote;

Если вы подадите отрицательное число по модулю, вы получите отрицательный результат. Если вам приходится иметь дело с отрицательными числами, то есть дополнительный шаг:

int note = -1;
var correctlyWrappedNote = note % 12; // will equal -1

if (correctlyWrappedNote < 0)
    correctlyWrappedNote = 12 + correctlyWrappedNote; // will equal 11

var actualNote = (NoteValue)correctlyWrappedNote; // Will equal Gsharp
2 голосов
/ 11 сентября 2011

@ Ответ Мерлина содержит суть того, что вам нужно сделать, но с использованием %12 только потому, что вашему члену enum присвоено 12, и потому что каждое число от 0 до 11 назначено одному из членов enum, является рецептом неработающегокод вниз по линии.Чтобы сделать его более устойчивым к изменениям, вы можете написать его так:

var notes = Enum.GetValues(typeof(NoteValue)); //array
var startingNote = Array.IndexOf(notes,NoteValue.Fsharp);//8
var fourNotesAfterStartingNote = notes[(startingNote+4)%notes.Length];//Asharp

Приведенный выше код будет продолжать работать правильно, даже если будет добавлена ​​новая заметка.Маловероятно, может быть, но опять же код всегда меняется:)

...