text: Q:
  
  C# reflection: If ... else?
  
  I'm currently facing new problem with operators. Using following code, I want to make output that would be same as when using if ... else pair in C#.
  var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
  var g = method.GetILGenerator();
  
  g.Emit(OpCodes.Ldstr, "string");
  g.Emit(OpCodes.Ldstr, "string");
  g.Emit(OpCodes.Call, typeof(String).GetMethod("op_Equality", new Type[]{typeof(string), typeof(string)}));
  g.Emit(OpCodes.Ldc_I4, 0);
  g.Emit(OpCodes.Ceq);
  g.Emit(OpCodes.Brtrue_S, );
  
  var action = (Action)method.CreateDelegate(typeof(Action));
  action();
  
  Console.Read();
  
  My questions are:
  
  How can I get the address of an instruction to pass it as a parameter for branch opcodes?
  Is there any difference between BR and BR_S, Brtrue and Brtrue_S, Brfalse and Brfalse_S and similar instructions?
  
  Thanks.
  
  A:
  
  You can use a combination of the DefineLabel and
  MarkLabel methods to determine the target location of the
  branch. To do so, declare the labels you'll need - something like
  equal and notequal. Then you can mark the spots in your IL where
  the labels should be present. Once this is done, you can set the
  target of your branch instruction to this label.
  // Define labels
  Label equal = g.DefineLabel();
  Label notEqual = g.DefineLabel();
  Label endOfMethod = g.DefineLabel();
  // your logic here
  g.Emit(OpCodes.Brtrue_S, equal);
  g.MarkLabel(equal);
  // some code if they are equal
  g.MarkLabel(notEqual);
  // some code if they are not equal
  g.MarkLabel(endOfMethod); // this marks the return point
  g.Emit(OpCodes.Ret);
  
  The difference between Br, Brtrue, and Brfalse and their _S
  counterparts is the length of the jump. The _S denotes short form;
  the target instruction is a 1-byte signed offset from the next instruction. In the standard (non-short) form, the target is
  represented by a 4-byte offset.
  
  A:
  
  ILGenerator.ILOffset gives you the current offset in the IL stream, if that's what you want. You can use DefineLabel and MarkLabel, too, as goric suggested.
  The only difference between brtrue.s and brtrue is that brtrue.s is the short version of brtrue. brtrue uses a 4-byte offset and brtrue.s uses a 1-byte offset. The same applies for brfalse and brfalse.s (and br/br.s).  
  Those are not the only short versions of an IL instruction, there are also other short instructions, like ldc.i4.0 - ldc.i4.8 for loading integers. Those are mainly useful for generating smaller binaries, but i don't think there is a big difference otherwise. 
  
  A:
  
  This is new to me, but from a little searching apparently you get the address by calling
  Label targetInstruction = g.DefineLabel();
  
  at some point beforehand (e.g. before your first Emit?), and then
  g.MarkLabel(targetInstruction);
  
  just before emitting the line you want to branch to. Then this Label is the argument to your Br____ opcode.
  The difference between Br, Brtrue and Brfalse is that Br always branches, and the other two pop a value off the stack and only branch if it is true or false respectively. (So yes, there is a big difference!) The _S signifies "short form" but I'm not sure what this means.
  
  