c# - 查找 Func 委托(delegate)的调用方法的名称

标签 c# reflection delegates func

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

 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 static class Invoker
            {        
                public static void invoke(Proxy proxy, Func<Proxy,string> online, string methodName){                       

                 if (IsCached(proxyName, methodName)){
                    output = GetFromCache(proxyName, methodName);
                 }else{       
                    output = online(proxy);
                 }

                }

            } 

解决方案 2:使用可能存在性能问题的 Expression

 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{       
                output = online.Compile()(proxy);
             }

            }

        } 

解决方案 3:使用 Expression 作为另一个参数(容易出错)。

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

             var methodName = ((MethodCallExpression)online2.Body).Method.Name;
             if (IsCached(proxyName, methodName)){
                output = GetFromCache(proxyName, methodName);
             }else{       
                output = online(proxy);
             }

            }

        }

你知道任何其他更好的方法来检查和获取 Invoker 需要的 methodName 吗?

注意:
我没有为在线函数结果搜索缓存机制,因为我已经有了它。
唯一的问题是此缓存需要在 Func 委托(delegate)中调用代理 methodName

最佳答案

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

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

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);
        }
    }
}

我尝试将您的代码改编为示例,希望它有意义。

关于c# - 查找 Func 委托(delegate)的调用方法的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28634006/

相关文章:

c# - 有没有办法在设置类的任何属性时调用方法?

c# - 无法通过 Exchange Server 2013 中的 EWS 加载 MimeContent

c# - 使用 Directory.GetFiles 时出现 UnauthorizedAccessException

java - 如何使用Java Reflect获取类级别注释值?

java - 我应该如何使用 guava TypeToken 反射性地实例化参数化类型?

ios - delegate = self 导致线程 1 : Fatal error: Unexpectedly found nil while unwrapping an Optional value

objective-c - iOS:释放正在使用的对象 (ARC)

c# - 如何在 WebForms 项目中启用 MVC?

c# - 同一程序集中的循环引用是一件坏事吗?

php - Zend 框架模块和反射