当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - 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((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);

}

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 :)

分享给朋友:
您可能感兴趣的文章:
随机阅读: