The dynamic method created with this constructor has access to all members of the type owner, and to public and internal (Friend in Visual Basic) members of all the other types in the module that contains owner.

The following code example creates a DynamicMethod that is logically associated with a type. This association gives it access to the private members of that type.

The code example defines a class named Example with a private field, a class named DerivedFromxample that derives from the first class, a delegate type named UseLikeStatic that returns Int32 and has parameters of type Example and Int32, and a delegate type named UseLikeInstance that returns Int32 and has one parameter of type Int32.

The example code then creates a DynamicMethod that changes the private field of an instance of Example and returns the previous value.

Note

In general, changing the internal fields of classes is not good object-oriented coding practice.

The example code creates an instance of Example and then creates two delegates. The first is of type UseLikeStatic, which has the same parameters as the dynamic method. The second is of type UseLikeInstance, which lacks the first parameter (of type Example). This delegate is created using the CreateDelegate(Type, Object) method overload; the second parameter of that method overload is an instance of Example, in this case the instance just created, which is bound to the newly created delegate. Whenever that delegate is invoked, the dynamic method acts on the bound instance of Example.

Note

This is an example of the relaxed rules for delegate binding introduced in the .NET Framework 2.0, along with new overloads of the Delegate.CreateDelegate method. For more information, see the Delegate class.

The UseLikeStatic delegate is invoked, passing in the instance of Example that is bound to the UseLikeInstance delegate. Then the UseLikeInstance delegate is invoked, so that both delegates act on the same instance of Example. The changes in the values of the internal field are displayed after each call. Finally, a UseLikeInstance delegate is bound to an instance of DerivedFromxample, and the delegate calls are repeated.

using System;
using System.Reflection;
using System.Reflection.Emit;
// These classes are for demonstration purposes. // publicclass Example
{
privateint id = 0;
public Example(int id)
{
this.id = id;
}
publicint ID { get { return id; }}
}
publicclass DerivedFromExample : Example
{
public DerivedFromExample(int id) : base(id) {}
}
// Two delegates are declared: UseLikeInstance treats the dynamic // method as if it were an instance method, and UseLikeStatic // treats the dynamic method in the ordinary fashion. // publicdelegateint UseLikeInstance(int newID);
publicdelegateint UseLikeStatic(Example ex, int newID);
publicclass Demo
{
publicstaticvoid Main()
{
// This dynamic method changes the private id field. It has // no name; it returns the old id value (return type int); // it takes two parameters, an instance of Example and // an int that is the new value of id; and it is declared // with Example as the owner type, so it can access all // members, public and private. //
DynamicMethod changeID = new DynamicMethod(
"",
typeof(int),
new Type[] { typeof(Example), typeof(int) },
typeof(Example)
);
// Get a FieldInfo for the private field 'id'.
FieldInfo fid = typeof(Example).GetField(
"id",
BindingFlags.NonPublic | BindingFlags.Instance
);
ILGenerator ilg = changeID.GetILGenerator();
// Push the current value of the id field onto the // evaluation stack. It's an instance field, so load the // instance of Example before accessing the field.
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldfld, fid);
// Load the instance of Example again, load the new value // of id, and store the new field value.
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Stfld, fid);
// The original value of the id field is now the only // thing on the stack, so return from the call.
ilg.Emit(OpCodes.Ret);
// Create a delegate that uses changeID in the ordinary // way, as a static method that takes an instance of // Example and an int. //
UseLikeStatic uls =
(UseLikeStatic) changeID.CreateDelegate(
typeof(UseLikeStatic)
);
// Create an instance of Example with an id of 42. //
Example ex = new Example(42);
// Create a delegate that is bound to the instance of // of Example. This is possible because the first // parameter of changeID is of type Example. The // delegate has all the parameters of changeID except // the first.
UseLikeInstance uli =
(UseLikeInstance) changeID.CreateDelegate(
typeof(UseLikeInstance),
ex
);
// First, change the value of id by calling changeID as // a static method, passing in the instance of Example. //
Console.WriteLine(
"Change the value of id; previous value: {0}",
uls(ex, 1492)
);
// Change the value of id again using the delegate bound // to the instance of Example. //
Console.WriteLine(
"Change the value of id; previous value: {0}",
uli(2700)
);
Console.WriteLine("Final value of id: {0}", ex.ID);
// Now repeat the process with a class that derives // from Example. //
DerivedFromExample dfex = new DerivedFromExample(71);
uli = (UseLikeInstance) changeID.CreateDelegate(
typeof(UseLikeInstance),
dfex
);
Console.WriteLine(
"Change the value of id; previous value: {0}",
uls(dfex, 73)
);
Console.WriteLine(
"Change the value of id; previous value: {0}",
uli(79)
);
Console.WriteLine("Final value of id: {0}", dfex.ID);
}
}
/* This code example produces the following output:
Change the value of id; previous value: 42
Change the value of id; previous value: 1492
Final value of id: 2700
Change the value of id; previous value: 71
Change the value of id; previous value: 73
Final value of id: 79
*/