本文整理汇总了C#中Mono.Cecil.Cil.MethodBody.Emit方法的典型用法代码示例。如果您正苦于以下问题:C# MethodBody.Emit方法的具体用法?C# MethodBody.Emit怎么用?C# MethodBody.Emit使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Mono.Cecil.Cil.MethodBody
的用法示例。
在下文中一共展示了MethodBody.Emit方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: ProxyMethod
protected virtual void ProxyMethod(MethodBody body, MethodReference proceedTargetMethod)
{
// Initialize method info in static constructor
var methodInfoFieldDefinition = new FieldDefinition(Name + "$Info", FieldAttributes.Private | FieldAttributes.Static, ClassWeaver.Context.MethodInfoType);
ClassWeaver.ProxyType.Fields.Add(methodInfoFieldDefinition);
FieldReference methodInfoField = methodInfoFieldDefinition;
FieldReference propertyInfoField = null;
PropertyDefinition property = null;
if (Method.IsSetter || Method.IsGetter)
{
property = ClassWeaver.PropertiesByAccessor[Method];
var propertyInfoFieldDeclaration = new FieldDefinition($"{Name}${(Method.IsGetter ? "Get" : "Set")}Info", FieldAttributes.Private | FieldAttributes.Static, ClassWeaver.Context.PropertyInfoType);
ClassWeaver.ProxyType.Fields.Add(propertyInfoFieldDeclaration);
propertyInfoField = propertyInfoFieldDeclaration;
}
StaticConstructor.Body.Emit(il =>
{
var methodDeclaringType = Import(Method.DeclaringType);
if (ClassWeaver.ProxyType.HasGenericParameters)
{
var genericProxyType = ClassWeaver.ProxyType.MakeGenericInstanceType(ClassWeaver.ProxyType.GenericParameters.ToArray());
methodInfoField = methodInfoField.Bind(genericProxyType);
propertyInfoField = propertyInfoField?.Bind(genericProxyType);
methodDeclaringType = ClassWeaver.SourceType.MakeGenericInstanceType(ClassWeaver.ProxyType.GenericParameters.ToArray());
}
var methodFinder = ClassWeaver.Context.MethodFinder.MakeGenericInstanceType(methodDeclaringType);
// Store MethodInfo into the static field
var methodSignature = Method.GenerateSignature();
var findMethod = ClassWeaver.Context.FindMethod.Bind(methodFinder);
il.Emit(OpCodes.Ldstr, methodSignature);
il.Emit(OpCodes.Call, findMethod);
il.Emit(OpCodes.Stsfld, methodInfoField);
if (property != null)
{
// Store PropertyInfo into the static field
var findProperty = ClassWeaver.Context.FindProperty.Bind(methodFinder);
il.Emit(OpCodes.Ldstr, methodSignature);
il.Emit(OpCodes.Call, findProperty);
il.Emit(OpCodes.Stsfld, propertyInfoField);
}
});
// Create proceed method (four different types). The proceed method is what you may call in your invocation handler
// in order to invoke the behavior that would have happened without the proxy. The actual behavior depends on the value
// of "target". If it's not null, it calls the equivalent method on "target". If it *is* null, then:
//
// * If it's an interface, it provides a default value
// * If it's not an interface, and the method is not abstract, it calls the base implementation of that class.
// * If it's abstract, then it provides a default value
//
// The actual implementation of proceed varies based on whether (where T represents the method's return type):
//
// * The method's return type is void (Represented by Action)
// * The method's return type is Task (Represented by Func<Task>)
// * The method's return type is Task<T> (Represented by Func<Task<T>>)
// * The method's return type is anything else (Represented by Func<T>)
SetUpTypes();
var proceed = new MethodDefinition("Proceed", MethodAttributes.Public | MethodAttributes.Static, ProceedReturnType.ResolveGenericParameter(ClassWeaver.ProxyType));
proceed.Parameters.Add(new ParameterDefinition(ClassWeaver.Context.InvocationType));
proceed.Body = new MethodBody(proceed);
proceed.Body.InitLocals = true;
ProceedClass.Methods.Add(proceed);
MethodReference proceedReference = proceed;
TypeReference proceedClass = ProceedClass;
if (ProceedClass.HasGenericParameters)
{
proceedReference = proceed.Bind(proceedClass.MakeGenericInstanceType(ClassWeaver.ProxyType.GenericParameters.Concat(body.Method.GenericParameters).ToArray()));
}
proceed.Body.Emit(il =>
{
ImplementProceed(Method, body, il, methodInfoField, proceedReference, EmitProceedTarget, proceedTargetMethod, GetProceedCallOpCode());
});
// Implement method
body.Emit(il =>
{
ImplementBody(il, methodInfoField, propertyInfoField, proceedReference, proceedTargetMethod);
});
}