【问题标题】:Enumerations values set to different numbers / resetting enumeration values枚举值设置为不同的数字/重置枚举值
【发布时间】:2011-11-14 17:14:32
【问题描述】:

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

我列举了不同的笔记:

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,而不是继续下去?

我会得到这样的东西(主要规模):

G 12 14 15 17 19

而不是

G 一种 乙 C D 乙 F#

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

【问题讨论】:

    标签: c# enums numbers int


    【解决方案1】:

    @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
    

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

    【讨论】:

    • Very unlikely,但你是对的 - 最好不要使用幻数,并根据逻辑运算(音符计数)而不是标记值进行计算。
    • 非常雄辩。我想从现在开始我会使用确切的词:)
    【解决方案2】:

    在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-08
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多