public SwitchPictureBox() { this.BackColor = Color.LightPink; SwitchValue = SwitchMethod.随机; }
/// <summary> /// Emits local variable switch and performs a specified operation on each case. /// </summary> /// <param name="codeGenerator">The code generator.</param> /// <param name="method">The operation performed in each case.</param> internal void EmitSwitch(CodeGenerator codeGenerator, SwitchMethod method) { ILEmitter il = codeGenerator.IL; Debug.Assert(method != null); Label default_case = il.DefineLabel(); Label end_label = il.DefineLabel(); LocalBuilder ivar_local = il.GetTemporaryLocal(Types.String[0], true); LocalBuilder non_interned_local = il.DeclareLocal(Types.String[0]); VariablesTable variables = codeGenerator.CurrentVariablesTable; Label[] labels = new Label[variables.Count]; // non_interned_local = <name expression>; EmitName(codeGenerator); il.Stloc(non_interned_local); // ivar_local = String.IsInterned(non_interned_local) il.Ldloc(non_interned_local); il.Emit(OpCodes.Call, Methods.String_IsInterned); il.Stloc(ivar_local); // switch for every compile-time variable: int i = 0; foreach (VariablesTable.Entry variable in variables) { labels[i] = il.DefineLabel(); // IF (ivar_local == <i-th variable name>) GOTO labels[i]; il.Ldloc(ivar_local); il.Emit(OpCodes.Ldstr, variable.VariableName.ToString()); il.Emit(OpCodes.Beq, labels[i]); i++; } // GOTO default_case: il.Emit(OpCodes.Br, default_case); // operation on each variable: i = 0; foreach (VariablesTable.Entry variable in variables) { // labels[i]: il.MarkLabel(labels[i]); // operation: method(codeGenerator, variable, null); // GOTO end; il.Emit(OpCodes.Br, end_label); i++; } // default case - new variable created at runtime: il.MarkLabel(default_case); method(codeGenerator, null, non_interned_local); // END: il.MarkLabel(end_label); }