// // Sample code to show late-bound set value on array // Written by Haibo Luo @ http://blogs.msdn.com/haibo_luo // // THIS CODE IS PROVIDED "AS IS", WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK // using System; using System.Reflection; using System.Reflection.Emit; using System.Security.Permissions; //[assembly: SecurityPermission(SecurityAction.RequestRefuse, SkipVerification = true)] class Test { static void Main() { ZeroLowerBound1DArray(); NonZeroLowerBound1DArray(); } delegate void MySetValue(Array array, int index, int value); static void ZeroLowerBound1DArray() { // creation: new int[5] Array x = Array.CreateInstance(typeof(int), 5); // 0. early-bind set: explicit cast to int[] int[] y = (int[])x; y[0] = 100; // 1. late-bound set via Array.SetValue x.SetValue(200, 1); // 2. late-bound set via DynamicMethod/Delegate/OpCodes.Stelem DynamicMethod dm = new DynamicMethod("SetValueByStelem", typeof(void), new Type[] { typeof(Array), typeof(int), typeof(int) }, typeof(Test)); ILGenerator ilgen = dm.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Castclass, x.GetType()); ilgen.Emit(OpCodes.Ldarg_1); // index ilgen.Emit(OpCodes.Ldarg_2); // value ilgen.Emit(OpCodes.Stelem_I4); ilgen.Emit(OpCodes.Ret); MySetValue sv = (MySetValue)dm.CreateDelegate(typeof(MySetValue)); sv(x, 2, 300); // 3. late-bound set via MethodInfo.Invoke of "Set" MethodInfo mi = x.GetType().GetMethod("Set"); mi.Invoke(x, new object[] { 3, 400 }); // 4. late-bound set via DynamicMethod/Delegate/"Set" dm = new DynamicMethod("SetValueBySet", typeof(void), new Type[] { typeof(Array), typeof(int), typeof(int) }, typeof(Test)); ilgen = dm.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Castclass, x.GetType()); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Call, mi); ilgen.Emit(OpCodes.Ret); sv = (MySetValue)dm.CreateDelegate(typeof(MySetValue)); sv(x, 4, 500); Array.ForEach(y, delegate(int a) { Console.WriteLine(a); }); } static void NonZeroLowerBound1DArray() { // creation: new int[-3..1] Array x = Array.CreateInstance(typeof(int), new int[] { 5 }, new int[] { -3 }); // 1. late-bound set via Array.SetValue x.SetValue(200, 1 - 3); // 3. late-bound set via MethodInfo.Invoke of "Set" MethodInfo mi = x.GetType().GetMethod("Set"); mi.Invoke(x, new object[] { 3 - 3, 400 }); // 4. late-bound set via DynamicMethod/Delegate/"Set" DynamicMethod dm = new DynamicMethod("SetValueBySet", typeof(void), new Type[] { typeof(Array), typeof(int), typeof(int) }, typeof(Test)); ILGenerator ilgen = dm.GetILGenerator(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Castclass, x.GetType()); ilgen.Emit(OpCodes.Ldarg_1); ilgen.Emit(OpCodes.Ldarg_2); ilgen.Emit(OpCodes.Call, mi); ilgen.Emit(OpCodes.Ret); MySetValue sv = (MySetValue)dm.CreateDelegate(typeof(MySetValue)); sv(x, 4 - 3, 500); for (int i = -3; i < 2; i++) { Console.WriteLine(x.GetValue(i)); } } static void MultiDimensionalArray() { int[,] array = new int[2, 2]; array[0, 1] = 1000; } }