15.01.2013 Views

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

Free-ebooks-library - Bahar Ali Khan

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

mb.DefineParameter (1, ParameterAttributes.None, "value");<br />

ILGenerator gen = mb.GetILGenerator();<br />

gen.Emit (OpCodes.Ldarg_0);<br />

gen.Emit (OpCodes.Ldarg_0);<br />

gen.Emit (OpCodes.Ldind_R8);<br />

gen.Emit (OpCodes.Call, typeof (Math).GetMethod ("Sqrt"));<br />

gen.Emit (OpCodes.Stind_R8);<br />

gen.Emit (OpCodes.Ret);<br />

Type realType = tb.CreateType();<br />

object[] args = { 10.0 };<br />

tb.GetMethod ("SquareRoot").Invoke (null, args);<br />

Console.WriteLine (args[0]); // 3.16227766016838<br />

The opcodes here were copied from a disassembled C# method. Notice the difference<br />

in semantics for accessing parameters passed by reference: Ldind and Stind<br />

mean “load indirectly” and “store indirectly,” respectively. The R8 suffix means an<br />

8-byte floating-point number.<br />

The process for emitting out parameters is identical, except that you call DefinePara<br />

meter as follows:<br />

mb.DefineParameter (1, ParameterAttributes.Out, "value");<br />

Generating instance methods<br />

To generate an instance method, specify MethodAttributes.Instance when calling<br />

DefineMethod:<br />

MethodBuilder mb = tb.DefineMethod ("SquareRoot",<br />

MethodAttributes.Instance | MethodAttributes.Public<br />

...<br />

With instance methods, argument zero is implicitly this; the remaining arguments<br />

start at 1. So, Ldarg_0 loads this onto the evaluation stack; Ldarg_1 loads the first<br />

real method argument.<br />

HideBySig<br />

If you’re subclassing another type, it’s nearly always worth specifying MethodAttri<br />

butes.HideBySig when defining methods. HideBySig ensures that C#-style method<br />

hiding semantics are applied, which is that a base method is hidden only if a subtype<br />

defines a method with an identical signature. Without HideBySig, method hiding<br />

considers only the name, so Foo(string) in the subtype will hide Foo() in the base<br />

type, which is generally undesirable.<br />

Emitting Fields and Properties<br />

To create a field, you call DefineField on a TypeBuilder, telling it the desired field<br />

name, type, and visibility. The following creates a private integer field called<br />

“length”:<br />

Emitting Type Members | 719<br />

Reflection

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!