Enumerations values set to different numbers / resetting enumeration values
I am trying to create a program that will calculate different musical scales based on the starting note that you provide.
I have an enumeration for the different notes:
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 then have a method that sets each note
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((startin开发者_高级运维gNote - 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);
}
The issue I'm having is that if it goes I start with G (which is 10 in my enumeration), it will just start printing numbers after G#. Can I make it so that it will return back to 0 after 11, rather than just keep going on?
I'll get something like this (for major scale):
G 12 14 15 17 19
instead of
G A B C D E F#
Is there any way to fix this? Thank you.
Enumerations as they are defined in C# are basically "strongly typed" wrappers for integral types (integers).
If you want this sort of wrapping behavior for integers, the common solution is to use the modulo (%
) operator:
int note = 12;
var correctlyWrappedNote = note % 12; // will equal 0
This is logically equivalent to taking a remainder after dividing by 12.
You should then be able to cast it back to your NoteValue
type:
var actualNote = (NoteValue)correctlyWrappedNote;
If you feed a negative number to modulo, though, you'll get a negative result. If you have to deal with negative numbers, then there's an extra step:
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
@Merlyn's answer contains the gist of what you need to do, but using %12
just because your enum member's happen to be 12 and because each number 0 through 11 is assigned to one of the enum members is a recipe for broken code down the line. To make it more change resilient, you could write it like this
var notes = Enum.GetValues(typeof(NoteValue)); //array
var startingNote = Array.IndexOf(notes,NoteValue.Fsharp);//8
var fourNotesAfterStartingNote = notes[(startingNote+4)%notes.Length];//Asharp
The above code will continue to function correctly even if a new note is added. Unlikely maybe- but then again code always changes :)
精彩评论