枚举值设置为不同的数字/重置枚举值

本文关键字:枚举 数字 设置 | 更新日期: 2023-09-27 18:08:09

我正在尝试创建一个程序,该程序将根据您提供的开始音符计算不同的音阶。

我有一个不同音符的枚举:

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
}

然后我有一个方法来设置每个音符

        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#后面的数字。我能让它回来吗11点后回到0,而不是继续前进?

我会得到这样的(对于大调音阶):

G1214151719日

不是

G一个BCDEf#

有办法解决这个问题吗?谢谢你。

枚举值设置为不同的数字/重置枚举值

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

@Merlyn的回答包含了您需要做的事情的要点,但是使用%12只是因为您的枚举成员恰好是12,并且因为每个数字0到11都分配给枚举成员之一,这是一行代码崩溃的秘诀。为了使它更适应变化,你可以这样写

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

即使添加了新的注释,上述代码也将继续正常运行。也许不太可能-但代码总是变化的:)