Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查找被调用的Func委托方法的名称_C#_Reflection_Delegates_Func - Fatal编程技术网

C# 查找被调用的Func委托方法的名称

C# 查找被调用的Func委托方法的名称,c#,reflection,delegates,func,C#,Reflection,Delegates,Func,我有一个简单的调用程序,为了能够使用缓存库,我需要知道对象的调用方法的名称,该对象是Func委托的参数 class Program { static void Main(string[] args) { var proxy = new Proxy(); Invoker.invoke(proxy, p => p.formatSomething("D

我有一个简单的调用程序,为了能够使用缓存库,我需要知道对象的调用方法的名称,该对象是
Func
委托的参数

 class Program
        {
            static void Main(string[] args)
            {
                var proxy = new Proxy();        
                Invoker.invoke(proxy, p => p.formatSomething("Dumb test"));       
            }
        }

        public class Proxy
        {
            public string formatSomething(string input){

                return String.Format("-===={0}====-", input);
            }
        }


        public static class Invoker
        {        
            public static void invoke(Proxy proxy, Func<Proxy,string> online){                       

             //Some caching logic that require the name of the method 
             //invoked on the proxy (in this specific case "formatSomething")    
             var methodName = ??; 
             if (IsCached(proxyName, methodName)){
                output = GetFromCache(proxyName, methodName);
             }else{       
                output = online(proxy);
             }
            }

        }        
解决方案3:使用
表达式
作为另一个参数(容易出错)

公共静态类调用程序
{        
公共静态void invoke(代理、在线函数、在线表达式2){
var methodName=((MethodCallExpression)online2.Body).Method.Name;
if(IsCached(proxyName,methodName)){
输出=GetFromCache(proxyName,methodName);
}否则{
输出=在线(代理);
}
}
}
您知道其他更好的方法来检查和获取调用程序需要的
methodName

注意:
我没有搜索在线函数结果的缓存机制,因为我已经有了它。

唯一的问题是此缓存需要在
Func
委托中调用的代理
methodName

检查以下代码。如果要获取方法全名,请在第一行
#define FULL_NAME

 class Program
        {
            static void Main(string[] args)
            {
                var proxy = new Proxy();        
                Invoker.invoke(proxy, p => p.formatSomething("Dumb test"));       
            }
        }

        public class Proxy
        {
            public string formatSomething(string input){

                return String.Format("-===={0}====-", input);
            }
        }


        public static class Invoker
        {        
            public static void invoke(Proxy proxy, Func<Proxy,string> online){                       

             //Some caching logic that require the name of the method 
             //invoked on the proxy (in this specific case "formatSomething")    
             var methodName = ??; 
             if (IsCached(proxyName, methodName)){
                output = GetFromCache(proxyName, methodName);
             }else{       
                output = online(proxy);
             }
            }

        }        
public class Cache
{
    private const uint DefaultCacheSize = 100;

    private readonly Dictionary<string, object> _cache = new Dictionary<string, object>();
    private readonly object _cacheLocker = new object();
    private readonly uint _cacheSize;

    public Cache(uint cacheSize = DefaultCacheSize)
    {
        _cacheSize = cacheSize;
    }

    public uint CacheSize
    {
        get { return _cacheSize; }
    }

    public TValue Resolve<TObj, TValue>(TObj item, Func<TObj, TValue> func, [CallerMemberName] string key = "")
    {
#if FULL_NAME
        var stackTrace = new StackTrace();
        var method = stackTrace.GetFrame(1).GetMethod();
        key = string.Format("{0}_{1}",
            method.DeclaringType == null ? string.Empty : method.DeclaringType.FullName,
            method.Name);
#endif
        return CacheResolver(item, func, key);
    }

    private TValue CacheResolver<TObj, TValue>(TObj item, Func<TObj, TValue> func, string key)
    {
        object res;
        if (_cache.TryGetValue(key, out res) && res is TValue)
        {
            return (TValue) res;
        }

        TValue result = func(item);

        lock (_cacheLocker)
        {
            _cache[key] = result;

            if (_cache.Keys.Count > DefaultCacheSize)
            {
                _cache.Remove(_cache.Keys.First());
            }
        }

        return result;
    }
}

您需要一个表达式来解析方法的调用名,但可以引入某种两级缓存:一级用于实际的方法调用(不会过期),另一级用于方法的调用结果(可能过期)

我认为,你的第二个解决方案走向了正确的方向;只需编译表达式一次

public static class Invoker {
    public static void Invoke(Proxy proxy, Expression<Func<Proxy,string>> online) {
        var methodName = ((MethodCallExpression)online.Body).Method.Name;

        if (IsCached(proxyName, methodName)) {
            output = GetFromCache(proxyName, methodName);
        } else {
            if (IsFuncCached(methodName)) {
                func = GetFuncFromCache(methodName);
            } else {
                func = online.Compile();
                // add func to "func cache"...
            }
            output = func(proxy);
        }
    }
}
公共静态类调用程序{
公共静态void调用(代理、在线表达式){
var methodName=((MethodCallExpression)online.Body).Method.Name;
if(IsCached(proxyName,methodName)){
输出=GetFromCache(proxyName,methodName);
}否则{
if(IsFuncCached(methodName)){
func=GetFuncFromCache(methodName);
}否则{
func=online.Compile();
//将func添加到“func缓存”。。。
}
输出=func(代理);
}
}
}

我试着将您的代码作为一个例子,希望它有意义。

我最近实现了一个用于检查CLR方法的IL指令的解决方案

您可以这样使用它:

using System;
using System.Linq;
using Reflection.IL;

namespace StackOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            var proxy = new Proxy();
            Invoker.invoke(proxy, p => p.formatSomething("Dumb test"));  
        }
    }

    public class Proxy
    {
        public string formatSomething(string input)
        {

            return String.Format("-===={0}====-", input);
        }
    }

    public static class Invoker
    {
        public static void invoke(Proxy proxy, Func<Proxy, string> online)
        {
            //Some caching logic that require the name of the method 
            //invoked on the proxy (in this specific case "formatSomething")    
            var methodName = online.GetCalledMethods().First().Name;

            Console.WriteLine(methodName);
        }
    }
}
使用系统;
使用System.Linq;
使用Reflection.IL;
命名空间堆栈溢出
{
班级计划
{
静态void Main(字符串[]参数)
{
var proxy=新代理();
Invoker.invoke(proxy,p=>p.formatSomething(“哑测试”);
}
}
公共类代理
{
公共字符串格式(字符串输入)
{
返回String.Format(“-=={0}===-”,输入);
}
}
公共静态类调用程序
{
公共静态无效调用(代理,Func在线)
{
//某些缓存逻辑需要方法的名称
//在代理上调用(在本例中为“formatSomething”)
var methodName=online.GetCalledMethods().First().Name;
Console.WriteLine(方法名);
}
}
}
请注意,代码没有经过彻底的测试或记录,但我认为它应该满足您的需要。这是:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;

namespace Reflection.IL
{
    public struct ILInstruction
    {
        public OpCode Code { get; private set; }
        public object Operand { get; private set; }

        internal ILInstruction(OpCode code, object operand)
            : this()
        {
            this.Code = code;
            this.Operand = operand;
        }

        public int Size
        {
            get { return this.Code.Size + GetOperandSize(this.Code.OperandType); }
        }

        public override string ToString()
        {
            return this.Operand == null ? this.Code.ToString() : string.Format(CultureInfo.InvariantCulture, "{0} {1}", this.Code, this.Operand);
        }

        private static int GetOperandSize(OperandType operandType)
        {
            switch (operandType)
            {
                case OperandType.InlineBrTarget:
                case OperandType.InlineField:
                case OperandType.InlineI:
                case OperandType.InlineMethod:
                case OperandType.InlineSig:
                case OperandType.InlineString:
                case OperandType.InlineSwitch:
                case OperandType.InlineTok:
                case OperandType.InlineType:
                    return sizeof(int);

                case OperandType.InlineI8:
                    return sizeof(long);

                case OperandType.InlineNone:
                    return 0;

                case OperandType.InlineR:
                    return sizeof(double);

                case OperandType.InlineVar:
                    return sizeof(short);

                case OperandType.ShortInlineBrTarget:
                case OperandType.ShortInlineI:
                case OperandType.ShortInlineVar:
                    return sizeof(byte);

                case OperandType.ShortInlineR:
                    return sizeof(float);

                default:
                    throw new InvalidOperationException();
            }
        }
    }

    public sealed class MethodBodyIL : IEnumerable<ILInstruction>
    {
        private readonly MethodBase method;

        public MethodBodyIL(MethodBase method)
        {
            if (method == null)
                throw new ArgumentNullException("method");

            this.method = method;
        }

        public Enumerator GetEnumerator()
        {
            var body = this.method.GetMethodBody();

            return new Enumerator(this.method.Module, this.method.DeclaringType.GetGenericArguments(), this.method.GetGenericArguments(), body.GetILAsByteArray(), body.LocalVariables);
        }

        IEnumerator<ILInstruction> IEnumerable<ILInstruction>.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public struct Enumerator : IEnumerator<ILInstruction>
        {
            private static readonly IDictionary<short, OpCode> codes = typeof(OpCodes).FindMembers(MemberTypes.Field, BindingFlags.Public | BindingFlags.Static, (m, criteria) => ((FieldInfo)m).FieldType == typeof(OpCode), null).Cast<FieldInfo>().Select(f => (OpCode)f.GetValue(null)).ToDictionary(c => c.Value);

            private readonly Module module;
            private readonly Type[] genericTypeArguments, genericMethodArguments;
            private readonly byte[] il;
            private readonly IList<LocalVariableInfo> localVariables;

            private int offset;
            private ILInstruction current;

            internal Enumerator(Module module, Type[] genericTypeArguments, Type[] genericMethodArguments, byte[] il, IList<LocalVariableInfo> localVariables)
            {
                this.module = module;
                this.genericTypeArguments = genericTypeArguments;
                this.genericMethodArguments = genericMethodArguments;
                this.il = il;
                this.localVariables = localVariables;

                this.offset = 0;
                this.current = default(ILInstruction);
            }

            public ILInstruction Current
            {
                get { return this.current; }
            }

            public bool MoveNext()
            {
                if (this.offset < this.il.Length)
                {
                    this.current = this.ReadInstruction();
                    return true;
                }
                else
                {
                    this.current = default(ILInstruction);
                    return false;
                }
            }

            public void Reset()
            {
                this.offset = 0;
                this.current = default(ILInstruction);
            }

            public void Dispose()
            {
                this.offset = this.il.Length;
                this.current = default(ILInstruction);
            }

            private ILInstruction ReadInstruction()
            {
                var code = this.ReadCode();

                return new ILInstruction(code, this.ReadOperand(code.OperandType));
            }

            private OpCode ReadCode()
            {
                var code = codes[this.ReadByte()];

                if (code.OpCodeType == OpCodeType.Prefix)
                    code = codes[(short)(code.Value << 8 | this.ReadByte())];

                return code;
            }

            private object ReadOperand(OperandType operandType)
            {
                switch (operandType)
                {
                    case OperandType.InlineBrTarget:
                    case OperandType.InlineI:
                    case OperandType.InlineSwitch:
                        return this.ReadInt32();

                    case OperandType.InlineField:
                    case OperandType.InlineMethod:
                    case OperandType.InlineTok:
                    case OperandType.InlineType:
                        return this.ReadMember();

                    case OperandType.InlineI8:
                        return this.ReadInt64();

                    case OperandType.InlineNone:
                        return null;

                    case OperandType.InlineR:
                        return this.ReadDouble();

                    case OperandType.InlineSig:
                        return this.ReadSignature();

                    case OperandType.InlineString:
                        return this.ReadString();

                    case OperandType.InlineVar:
                        return this.ReadLocalVariable();

                    case OperandType.ShortInlineBrTarget:
                    case OperandType.ShortInlineI:
                        return this.ReadByte();

                    case OperandType.ShortInlineR:
                        return this.ReadSingle();

                    case OperandType.ShortInlineVar:
                        return this.ReadLocalVariableShort();

                    default:
                        throw new InvalidOperationException();
                }
            }

            private byte ReadByte()
            {
                var value = this.il[this.offset];
                ++this.offset;

                return value;
            }

            private short ReadInt16()
            {
                var value = BitConverter.ToInt16(this.il, this.offset);
                this.offset += sizeof(short);

                return value;
            }

            private int ReadInt32()
            {
                var value = BitConverter.ToInt32(this.il, this.offset);
                this.offset += sizeof(int);

                return value;
            }

            private long ReadInt64()
            {
                var value = BitConverter.ToInt64(this.il, this.offset);
                this.offset += sizeof(long);

                return value;
            }

            private float ReadSingle()
            {
                var value = BitConverter.ToSingle(this.il, this.offset);
                this.offset += sizeof(float);

                return value;
            }

            private double ReadDouble()
            {
                var value = BitConverter.ToDouble(this.il, this.offset);
                this.offset += sizeof(double);

                return value;
            }

            private MemberInfo ReadMember()
            {
                return this.module.ResolveMember(this.ReadInt32(), this.genericTypeArguments, this.genericMethodArguments);
            }

            private byte[] ReadSignature()
            {
                return this.module.ResolveSignature(this.ReadInt32());
            }

            private string ReadString()
            {
                return this.module.ResolveString(this.ReadInt32());
            }

            private LocalVariableInfo ReadLocalVariable()
            {
                return this.localVariables[this.ReadInt16()];
            }

            private LocalVariableInfo ReadLocalVariableShort()
            {
                return this.localVariables[this.ReadByte()];
            }

            object IEnumerator.Current
            {
                get { return this.Current; }
            }
        }
    }

    public static class ILHelper
    {
        public static MethodBodyIL GetIL(this MethodBase method)
        {
            return new MethodBodyIL(method);
        }

        public static IEnumerable<MethodBase> GetCalledMethods(this Delegate methodPtr)
        {
            if (methodPtr == null)
                throw new ArgumentNullException("methodPtr");

            foreach (var instruction in methodPtr.Method.GetIL())
                if (IsMethodCall(instruction.Code))
                    yield return (MethodBase)instruction.Operand;
        }

        private static bool IsMethodCall(OpCode code)
        {
            return code == OpCodes.Call || code == OpCodes.Calli || code == OpCodes.Callvirt;
        }
    }
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
利用制度全球化;
使用System.Linq;
运用系统反思;
使用System.Reflection.Emit;
名称空间反射.IL
{
公共结构
{
公共操作码{get;private set;}
公共对象操作数{get;private set;}
内部指令(操作码、对象操作数)
:此()
{
这个。代码=代码;
操作数=操作数;
}
公共整数大小
{
获取{返回this.Code.Size+getOperationSize(this.Code.OperationType);}
}
公共重写字符串ToString()
{
返回this.operant==null?this.Code.ToString():string.Format(CultureInfo.InvariantCulture,“{0}{1}”、this.Code、this.operant);
}
私有静态整型GetOperationSize(操作数类型操作数类型)
{
开关(操作数类型)
{
大小写操作数类型.INLINEBR目标:
大小写操作数类型.InlineField:
大小写操作数类型.InlineI:
案例操作数类型.INLINE方法:
大小写操作数类型.InlineSig:
大小写操作数类型.InlineString:
大小写操作数类型.INLINE开关:
大小写操作数类型.InlineTok:
大小写操作数类型。InlineType:
返回sizeof(int);
大小写操作数类型.InlineI8:
返回sizeof(长);
大小写操作数类型.inlineOne:
返回0;
大小写操作数类型.InlineR:
返回sizeof(双倍);
大小写操作数类型.InlineVar:
返回sizeof(短);
大小写操作数类型.ShortInlineBrTarget:
大小写操作数类型.ShortInlineI:
大小写操作数类型.ShortInlineVar:
返回sizeof(字节);
大小写操作数类型.ShortInlineR:
返回sizeof(浮动);
违约:
抛出新的InvalidOperationException();
}
}
}
公共密封类MethodBodyIL:IEnumerable
{
私有只读MethodBase方法;
公共MethodBodyIL(MethodBase方法)
{
if(方法==null)
抛出新的ArgumentNullException(“方法”);
这个方法=方法;
}
公共枚举器GetEnumerator()
{
var body=this.method.GetMethodBody();
返回新枚举数(this.met)
private string GetExpressionMethodCallName<T, T1>(Expression<Func<T, T1>> exp)
{
    var mce = exp.Body as MethodCallExpression;
    if (mce == null)
        throw new InvalidOperationException("invalid expression");

    return mce.Method.Name;
}
public static class Invoker {
    public static void Invoke(Proxy proxy, Expression<Func<Proxy,string>> online) {
        var methodName = ((MethodCallExpression)online.Body).Method.Name;

        if (IsCached(proxyName, methodName)) {
            output = GetFromCache(proxyName, methodName);
        } else {
            if (IsFuncCached(methodName)) {
                func = GetFuncFromCache(methodName);
            } else {
                func = online.Compile();
                // add func to "func cache"...
            }
            output = func(proxy);
        }
    }
}
using System;
using System.Linq;
using Reflection.IL;

namespace StackOverflow
{
    class Program
    {
        static void Main(string[] args)
        {
            var proxy = new Proxy();
            Invoker.invoke(proxy, p => p.formatSomething("Dumb test"));  
        }
    }

    public class Proxy
    {
        public string formatSomething(string input)
        {

            return String.Format("-===={0}====-", input);
        }
    }

    public static class Invoker
    {
        public static void invoke(Proxy proxy, Func<Proxy, string> online)
        {
            //Some caching logic that require the name of the method 
            //invoked on the proxy (in this specific case "formatSomething")    
            var methodName = online.GetCalledMethods().First().Name;

            Console.WriteLine(methodName);
        }
    }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;

namespace Reflection.IL
{
    public struct ILInstruction
    {
        public OpCode Code { get; private set; }
        public object Operand { get; private set; }

        internal ILInstruction(OpCode code, object operand)
            : this()
        {
            this.Code = code;
            this.Operand = operand;
        }

        public int Size
        {
            get { return this.Code.Size + GetOperandSize(this.Code.OperandType); }
        }

        public override string ToString()
        {
            return this.Operand == null ? this.Code.ToString() : string.Format(CultureInfo.InvariantCulture, "{0} {1}", this.Code, this.Operand);
        }

        private static int GetOperandSize(OperandType operandType)
        {
            switch (operandType)
            {
                case OperandType.InlineBrTarget:
                case OperandType.InlineField:
                case OperandType.InlineI:
                case OperandType.InlineMethod:
                case OperandType.InlineSig:
                case OperandType.InlineString:
                case OperandType.InlineSwitch:
                case OperandType.InlineTok:
                case OperandType.InlineType:
                    return sizeof(int);

                case OperandType.InlineI8:
                    return sizeof(long);

                case OperandType.InlineNone:
                    return 0;

                case OperandType.InlineR:
                    return sizeof(double);

                case OperandType.InlineVar:
                    return sizeof(short);

                case OperandType.ShortInlineBrTarget:
                case OperandType.ShortInlineI:
                case OperandType.ShortInlineVar:
                    return sizeof(byte);

                case OperandType.ShortInlineR:
                    return sizeof(float);

                default:
                    throw new InvalidOperationException();
            }
        }
    }

    public sealed class MethodBodyIL : IEnumerable<ILInstruction>
    {
        private readonly MethodBase method;

        public MethodBodyIL(MethodBase method)
        {
            if (method == null)
                throw new ArgumentNullException("method");

            this.method = method;
        }

        public Enumerator GetEnumerator()
        {
            var body = this.method.GetMethodBody();

            return new Enumerator(this.method.Module, this.method.DeclaringType.GetGenericArguments(), this.method.GetGenericArguments(), body.GetILAsByteArray(), body.LocalVariables);
        }

        IEnumerator<ILInstruction> IEnumerable<ILInstruction>.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        public struct Enumerator : IEnumerator<ILInstruction>
        {
            private static readonly IDictionary<short, OpCode> codes = typeof(OpCodes).FindMembers(MemberTypes.Field, BindingFlags.Public | BindingFlags.Static, (m, criteria) => ((FieldInfo)m).FieldType == typeof(OpCode), null).Cast<FieldInfo>().Select(f => (OpCode)f.GetValue(null)).ToDictionary(c => c.Value);

            private readonly Module module;
            private readonly Type[] genericTypeArguments, genericMethodArguments;
            private readonly byte[] il;
            private readonly IList<LocalVariableInfo> localVariables;

            private int offset;
            private ILInstruction current;

            internal Enumerator(Module module, Type[] genericTypeArguments, Type[] genericMethodArguments, byte[] il, IList<LocalVariableInfo> localVariables)
            {
                this.module = module;
                this.genericTypeArguments = genericTypeArguments;
                this.genericMethodArguments = genericMethodArguments;
                this.il = il;
                this.localVariables = localVariables;

                this.offset = 0;
                this.current = default(ILInstruction);
            }

            public ILInstruction Current
            {
                get { return this.current; }
            }

            public bool MoveNext()
            {
                if (this.offset < this.il.Length)
                {
                    this.current = this.ReadInstruction();
                    return true;
                }
                else
                {
                    this.current = default(ILInstruction);
                    return false;
                }
            }

            public void Reset()
            {
                this.offset = 0;
                this.current = default(ILInstruction);
            }

            public void Dispose()
            {
                this.offset = this.il.Length;
                this.current = default(ILInstruction);
            }

            private ILInstruction ReadInstruction()
            {
                var code = this.ReadCode();

                return new ILInstruction(code, this.ReadOperand(code.OperandType));
            }

            private OpCode ReadCode()
            {
                var code = codes[this.ReadByte()];

                if (code.OpCodeType == OpCodeType.Prefix)
                    code = codes[(short)(code.Value << 8 | this.ReadByte())];

                return code;
            }

            private object ReadOperand(OperandType operandType)
            {
                switch (operandType)
                {
                    case OperandType.InlineBrTarget:
                    case OperandType.InlineI:
                    case OperandType.InlineSwitch:
                        return this.ReadInt32();

                    case OperandType.InlineField:
                    case OperandType.InlineMethod:
                    case OperandType.InlineTok:
                    case OperandType.InlineType:
                        return this.ReadMember();

                    case OperandType.InlineI8:
                        return this.ReadInt64();

                    case OperandType.InlineNone:
                        return null;

                    case OperandType.InlineR:
                        return this.ReadDouble();

                    case OperandType.InlineSig:
                        return this.ReadSignature();

                    case OperandType.InlineString:
                        return this.ReadString();

                    case OperandType.InlineVar:
                        return this.ReadLocalVariable();

                    case OperandType.ShortInlineBrTarget:
                    case OperandType.ShortInlineI:
                        return this.ReadByte();

                    case OperandType.ShortInlineR:
                        return this.ReadSingle();

                    case OperandType.ShortInlineVar:
                        return this.ReadLocalVariableShort();

                    default:
                        throw new InvalidOperationException();
                }
            }

            private byte ReadByte()
            {
                var value = this.il[this.offset];
                ++this.offset;

                return value;
            }

            private short ReadInt16()
            {
                var value = BitConverter.ToInt16(this.il, this.offset);
                this.offset += sizeof(short);

                return value;
            }

            private int ReadInt32()
            {
                var value = BitConverter.ToInt32(this.il, this.offset);
                this.offset += sizeof(int);

                return value;
            }

            private long ReadInt64()
            {
                var value = BitConverter.ToInt64(this.il, this.offset);
                this.offset += sizeof(long);

                return value;
            }

            private float ReadSingle()
            {
                var value = BitConverter.ToSingle(this.il, this.offset);
                this.offset += sizeof(float);

                return value;
            }

            private double ReadDouble()
            {
                var value = BitConverter.ToDouble(this.il, this.offset);
                this.offset += sizeof(double);

                return value;
            }

            private MemberInfo ReadMember()
            {
                return this.module.ResolveMember(this.ReadInt32(), this.genericTypeArguments, this.genericMethodArguments);
            }

            private byte[] ReadSignature()
            {
                return this.module.ResolveSignature(this.ReadInt32());
            }

            private string ReadString()
            {
                return this.module.ResolveString(this.ReadInt32());
            }

            private LocalVariableInfo ReadLocalVariable()
            {
                return this.localVariables[this.ReadInt16()];
            }

            private LocalVariableInfo ReadLocalVariableShort()
            {
                return this.localVariables[this.ReadByte()];
            }

            object IEnumerator.Current
            {
                get { return this.Current; }
            }
        }
    }

    public static class ILHelper
    {
        public static MethodBodyIL GetIL(this MethodBase method)
        {
            return new MethodBodyIL(method);
        }

        public static IEnumerable<MethodBase> GetCalledMethods(this Delegate methodPtr)
        {
            if (methodPtr == null)
                throw new ArgumentNullException("methodPtr");

            foreach (var instruction in methodPtr.Method.GetIL())
                if (IsMethodCall(instruction.Code))
                    yield return (MethodBase)instruction.Operand;
        }

        private static bool IsMethodCall(OpCode code)
        {
            return code == OpCodes.Call || code == OpCodes.Calli || code == OpCodes.Callvirt;
        }
    }
}
public static class Invoker
{
    public static void invoke(Proxy proxy, Func<Proxy, string> online)
    {
       //Some caching logic that require the name of the method 
       //invoked on the proxy (in this specific case "formatSomething")    
       var methodName = online.Method.Name;
    }
}