我有一个简单的调用程序,为了能够使用缓存库,我需要知道作为 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/