将没有名称的MethodInfo作为字符串

时间:2010-03-04 12:16:05

标签: c# linq

我正在从LINQ表达式构建SQL表达式并且非常喜欢它。然而,重构问题已经出现。假设我想检查MethodCallExpression的方法,我会这样做:

MethodCallExpression expr = ...  // An expression from somewhere...

if (expr.Method == typeof(SqlFilterExtensions).GetMethod("Like", BindingFlags.Static | BindingFlags.Public))
{
    // Generate the SQL...
}

效果很好,但是如果有人要重命名,移动或以某种方式改变方法,这将无声地失败。

我想出了一个想法,但我觉得它很丑陋......

if (expr.Method == new Func<string,string,bool>(SqlFilterExtensions.Like).Method)
{
    // Generate the SQL...
}

3 个答案:

答案 0 :(得分:1)

  1. 如果你有单元测试来测试它,它就不会无声地失败。
  2. 如果您使用了ReSharper,则可以在重命名方法的同时更改字符串文字中的文本。

答案 1 :(得分:1)

我不明白你在做什么,我想你可能完全避免你在这里展示的一些代码。

我写了这个“GetMemberName”扩展方法,你可能可以用这段代码做点什么:

public static string GetMemberName<T, TResult>(
    this T anyObject, 
    Expression<Func<T, TResult>> expression)
{
    return ((MemberExpression)expression.Body).Member.Name;
}

// call as extension method, if you have a instance
string lengthPropertyName = "abc".GetMemberName(x => x.Length);

// or call as a static method, by providing the type in the argument
string lengthPropertyName = ReflectionUtility.GetMemberName(
    (string x) => x.Length);

修改

只是为了草拟解决方案:

public static bool IsMethod<TResult>(
  MethodInfo method, 
  Expression<Func<TResult>> expression)
{
  // I think this doesn't work like this, evaluate static method call
  return method == ((MemberExpression)expression.Body).Member;
}

if (IsMethod(expr.Method, () => SqlFilterExtensions.Like))
{
  // generate SQL
}

答案 2 :(得分:0)

如果您可以控制Like方法,也许您可​​以直接在那里工作,而不是稍后检查表达式。

如果您无法控制该方法,则除了通过比较名称

之外没有别的办法