让我们成像,我们发出一个代表圆的类。我们定义一个代表其半径的双重属性,并且关联后台字段和get/set访问器。然后,我们使用新创建的PropertyBuilder以匿名方法的形式准备计算区域的逻辑。访问自动创建匿名类型字段
var assemblyName = new AssemblyName();
assemblyName.Name = "SampleAssembly";
var domain = Thread.GetDomain();
var assembly = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
var module = assembly.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll", true);
var baseType = typeof(object);
var type = module.DefineType("Circle", TypeAttributes.Public, baseType);
var propertyType = typeof(double);
var radiusProperty = type.DefineProperty("Radius", PropertyAttributes.None, propertyType, null);
var backingField = type.DefineField("<Radius>k__BackingField", propertyType, FieldAttributes.Private);
var getter = type.DefineMethod("get_Radius", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, propertyType, null);
var getterIl = getter.GetILGenerator();
getterIl.Emit(OpCodes.Ldarg_0);
getterIl.Emit(OpCodes.Ldfld, backingField);
getterIl.Emit(OpCodes.Ret);
radiusProperty.SetGetMethod(getter);
var setter = type.DefineMethod("set_Radius", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName, null, new Type[] { propertyType });
var valueParameter = setter.DefineParameter(1, ParameterAttributes.None, "value");
var setterIl = setter.GetILGenerator();
setterIl.Emit(OpCodes.Ldarg_0);
setterIl.Emit(OpCodes.Ldarg_1);
setterIl.Emit(OpCodes.Stfld, backingField);
setterIl.Emit(OpCodes.Ret);
radiusProperty.SetSetMethod(setter);
Func<double> circleAreaExpression =() => Math.PI * Math.Pow((double)radiusProperty.GetValue(this), 2);
var or = new OperationReader(circleAreaExpression.Method);
var frame = new StackFrame();
var body = frame.GetMethod().GetMethodBody();
var locals = body.LocalVariables;
检查匿名方法的中间语言表明,它含有加载现场radiusProperty操作,其中 radiusProperty是我们新创建PropertyBuilder,保留一些匿名类的字段。
or.Operations {System.Reflection.Operation [11]} System.Reflection.Operation []
+ [0] {0000:ldc.r81414344187} System.Reflection.Operation
+ [1] {0009:ldarg.0} System.Reflection.Operation
+ [2] {0010:ldfld System.Reflection.Emit.PropertyBuilder MethodTest.Program + <> c__DisplayClass0_0 :: radiusProperty}
系统。 Reflection.Operation+ [3] {0015:ldarg.0} System.Reflection.Operation
+ [4] {0016:ldfld MethodTest.Program MethodTest.Program + <> c__DisplayClass0_0 :: <> 4__this} 系统.Reflection.Operation
+ [5] {0021:callvirt实例System.Object的System.Reflection.PropertyInfo ::的GetValue()}
System.Reflection.Operation+ [6] {0026:拆箱.any System.Double} System.Reflection.Operat离子
+ [7] {0031:ldc.r81073741824} System.Reflection.Operation
+ [8] {0040:调用System.Double System.Math ::的Pow()} System.Reflection.Operation
+ [9] {0045:MUL} System.Reflection.Operation
+ [10] {0046:滞留} System.Reflection.Operation
我们想什么,现在来实现的,是得到我们的原始PropertyBuilder,它是一个提到匿名类的领域。浏览我们当前所在方法体的局部变量,显示有趣的匿名类自豪地拥有局部变量数组中的第一个位置。虽然我们没有任何对这个匿名类实例的引用。 任何提示如何获得有趣的PropertyBuilder的参考?
当地人计数= 19 System.Collections.Generic.IList {System.Collections.ObjectModel.ReadOnlyCollection}
+ [0] {MethodTest.Program + <> c__DisplayClass0_0(0)}
的System.Reflection。LocalVariableInfo>+ [1] {System.Reflection.AssemblyName(1)}
System.Reflection.LocalVariableInfo+ [2] {System.AppDomain(2)} System.Reflection.LocalVariableInfo
+ [3] {System.Reflection.Emit.AssemblyBuilder(3)} System.Reflection.LocalVariableInfo>
+ [4] {System.Reflection.Emit.ModuleBuilder(4)}
系统。 Reflection.LocalVa riableInfo>+ [5] {System.Type的(5)} System.Reflection.LocalVariableInfo
+ [6] {System.Reflection.Emit.TypeBuilder(6)}
System.Reflection.LocalVariableInfo+ [7] {System.Type的(7)} System.Reflection.LocalVariableInfo
+ [8] {System.Reflection.Emit.FieldBuilder(8)}
System.Reflection.LocalVariableInfo+ [9] {System.Reflection.Emit.MethodBuilder(9)}
System.Reflection.LocalVariableInfo+ [10] {System.Reflection.Emit.ILGenerator(10)}
的System.Reflection .LocalVariableInfo+ [11] {System.Reflection.Emit.MethodBuilder(11)} System.Reflection.LocalVariableInfo
+ [12] {System.Reflection.Emit.ParameterBuilder(12)}
System.Reflection.LocalVariableInfo+ [13] {System.Reflection.Emit.ILGenerator(13)}
System.Reflection.LocalVariableInfo+ [14] {System.Func``1 [System.Double](14)} System.Reflection.LocalVariableInfo
+ [15] {System.Reflection.OperationReader(15)}
System.Reflection.LocalVariableInfo+ [16] {System.Diagnostics.StackFrame(16)} System.Reflection.LocalVariableInfo
+ [17] {System.Reflection.MethodBody(17)} System.Reflection.LocalVariableInfo
+ [18] {System.Collections.Generic.IList`1 [System.Reflection.LocalVariableInfo] (18)} System.Reflection。LocalVariableInfo
如何跳过所有的反射,使你的方法需要一个通用的anoymous类型和'Func键的'所以你可以选择呼叫时的半径? –