【问题标题】:Method name ToString()方法名 ToString()
【发布时间】:2011-07-13 17:51:25
【问题描述】:
GetCached(BLCustomer.GetAll, "GetAll");

其中"GetAll" 是会话密钥。 我该怎么做?

GetCached(BLCustomer.GetAll, BLCustomer.GetAll.ToString());

更新:

其他世界我想从方法名称BLCustomer.GetAll() 中获取字符串 "GetAll"(不是客户名称,而是方法名称)。

我想用这样的东西

GetCached(BLCustomer.GetSingle, BLCustomer.GetSingle.ToString());

而不是

GetCached(BLCustomer.GetSingle, "GetSingle");

避免硬编码方法名称。

【问题讨论】:

  • GetAll 返回什么类型?
  • BLCustomer 中的 GetAll 是什么?
  • 我收到了这个问题。 BLCustomer.GetSingleBLCustomer.GetAll 是静态属性吗?
  • ?UPDATE: 的顶部是什么意思?
  • @JohnnyCageWins,这意味着问题的标志。

标签: c# .net-4.0


【解决方案1】:

像这样更改 GetCached:

ReturnType GetCached(SomeFunc f)
{
  var methodname = f.Method.Name;
  // add rest of code
}

假设:

我猜GetCached目前实际上是这样的:

T GetCached<T>(Func<T> accessor, string name)
{
   ...
}

鉴于accessor已经是一个委托,名称可以如上图确定。

如果没有,我的建议将不起作用。

上面还假设BLCustomer.GetSingle是一个方法(instance或者static应该都可以)。

然后调用将是:

var r = GetCached(BLCustomer.GetSingle); // delegate implicitly created

【讨论】:

  • 你能详细说明一下吗?我不明白。 SomeFunc 是什么?
  • @Daniel Hilgarth:一些委托,这是我的假设,没有 GetCached 方法的签名。
  • @Daniel Hilgarth:更新了我的答案,现在应该更清楚了:)
【解决方案2】:

简单的解决方案:(从下面的 leppie 偷来的)

只需从 GetCached 方法中删除第二个参数:

ReturnType GetCached(Func<T> func)
{
    var name = func.Method.Name;

    // execute func here
}

假设它会被这样调用:

GetCached(BLCustomer.GetAll);

不是这样的:

GetCached(() => BLCustomer.GetAll());

复杂的解决方案:

你可以这样做:

string GetMethodName(Expression<Func<Func<dynamic>>> methodExpression)
{
    dynamic memberExpression = methodExpression.Body;
    MethodInfo result = memberExpression.Operand.Arguments[2].Value;
    return result.Name;
}

这样称呼它:

GetCached(BLCustomer.GetSingle, GetMethodName(() => BLCustomer.GetSingle));

这种方法做了两个假设:

  1. 调用总是需要像示例中的那样,即它不能有参数,并且委托的主体必须只包含您想要名称的方法,而不是其他任何东西
  2. 您想要命名的方法不能是void 类型并且不能有任何参数。

您也可以将其用于非静态方法:

BLCustomer customer = new BLCustomer();
GetCached(customer.GetSingle, GetMethodName(() => customer.GetSingle));

您甚至可以将 GetCached 更改为以下内容以清理其 API:

ReturnType GetCached<T>(Expression<Func<Func<T>>> methodExpression)
{
    var name = GetMethodName(methodExpression);
    var func = methodExpression.Compile()();

    // execute func and do stuff
}

为此,您需要将GetMethodName 设为通用,而不是使用dynamic

string GetMethodName<T>(Expression<Func<Func<T>>> methodExpression)
{
    dynamic memberExpression = methodExpression.Body;
    MethodInfo result = memberExpression.Operand.Arguments[2].Value;
    return result.Name;
}

然后你可以这样称呼它:

GetCached<IEnumerable<Customer>>(() => BLCustomer.GetAll)
GetCached<Customer>(() => BLCustomer.GetSingle)

【讨论】:

  • 您的方法越来越接近我的建议。我认为你真的不需要使用Expression,除非你涉及到闭包(根据你的例子)。再说一次,我可能做了太多假设:)
  • @leppie:我不知道这是可能的......你的回答应该是被接受的!就像我目前的情况一样,我将更新我的答案以展示如何以简单的方式做到这一点,因为我认为你的答案有点短:-)
  • 谢谢,但我仍然觉得这里有太多假设要给出准确的答案:)
  • @leppie:你是对的。但我认为我们现在向他展示了所有可能性 ;-)
  • 你能指出GetCached(BLCustomer.GetAll);GetCached(() =&gt; BLCustomer.GetAll());之间的区别吗?我一直认为它是完全一样的,但它似乎不是。
猜你喜欢
  • 2016-07-21
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-25
相关资源
最近更新 更多