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

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Emitting Methods<br />

You can specify a return type and parameter types when calling DefineMethod, in the<br />

same manner as when instantiating a DynamicMethod; e.g., the following method:<br />

public static double SquareRoot (double value)<br />

{<br />

return Math.Sqrt (value);<br />

}<br />

can be generated like this:<br />

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

MethodAttributes.Static | MethodAttributes.Public,<br />

CallingConventions.Standard,<br />

typeof (double), // Return type<br />

new[] { typeof (double) } ); // Parameter types<br />

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

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

gen.Emit (OpCodes.Ldarg_0); // Load 1st arg<br />

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

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

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

double x = (double) tb.GetMethod ("SquareRoot").Invoke (null,<br />

new object[] { 10.0 });<br />

Console.WriteLine (x); // 3.16227766016838<br />

Calling DefineParameter is optional and is typically done to assign the parameter a<br />

name. The number 1 refers to the first parameter (0 refers to the return value). If you<br />

call DefineParameter, the parameter is implicitly named __p1, __p2, and so on. Assigning<br />

names makes sense if you will write the assembly to disk; it makes your<br />

methods friendly to consumers.<br />

DefineParameter returns a ParameterBuilder object upon which<br />

you can call SetCustomAttribute to attach attributes (see “Attaching<br />

Attributes” on page 722, later in this chapter).<br />

To emit pass-by-reference parameters, such as in the following C# method:<br />

public static void SquareRoot (ref double value)<br />

{<br />

value = Math.Sqrt (value);<br />

}<br />

call MakeByRefType on the parameter type(s):<br />

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

MethodAttributes.Static | MethodAttributes.Public,<br />

CallingConventions.Standard,<br />

null,<br />

new Type[] { typeof (double).MakeByRefType() } );<br />

718 | Chapter 18: Reflection and Metadata

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

Saved successfully!

Ooh no, something went wrong!