为将两个对象字符串连接创建表达式树

3

我正在学习有关表达式和它们的表达式树,以便将它们与IronPython一起使用(但现在这并不重要)。

我想做的是创建一个类似于以下lambda表达式的表达式树:

Func<T, int, string> func = (s,t) => s + t;

我的当前函数是这样的:

public static Expression<Func<T, int, string>> StringConcatSelector<T>()
{
    var parameterParam = Expression.Parameter(typeof(T), "x");
    var paramToString = typeof(T).GetMethods().FirstOrDefault(s=>s.Name=="ToString");
    var parameter = Expression.Call(parameterParam, paramToString);


    var intParameterParam = Expression.Parameter(typeof(int), "s");
    var intParameterToString = typeof(int).GetMethods().FirstOrDefault(s => s.Name == "ToString");
    var intParameter = Expression.Call(intParameterParam, intParameterToString);

    var stringConcat = typeof(string).GetMethods().FirstOrDefault(s => s.Name == "Concat");

    var result = Expression.Call(stringConcat, parameter, intParameter);

    return Expression.Lambda<Func<T, int, string>>
                         (result, parameterParam, intParameterParam);
}

Expression.Call调用String.Concat的方式行不通,因为参数数量无效。

所以我认为需要以下步骤:

  • 创建一个List<string>类型的变量表达式。
  • 将两个值添加到列表中。
  • 使用列表表达式作为String.Concat的参数。

如果我是对的,那么如何创建一个List变量(或数组),并将两个值添加到其中,以便将其作为我的String.Concat的参数?

1个回答

7

String.Concat 方法有 11 种不同的重载,你正在随机选择一个。

对于您的情况,最合适的是:

public static String Concat(String str0, String str1)

您可以通过使用以下Type.GetMethod重载函数来获取它们。

public MethodInfo GetMethod(string name, Type[] types)

其中,types 数组代表方法参数的类型:

var stringConcat = typeof(string).GetMethod("Concat",
    new[] { typeof(string), typeof(string) });

1
哦,是的,我一直在犯傻。太好了,它完美地运作 :) - Matthias Burger
1
或者你可以使用 new [] {typeof(object), typeof(object)} 来调用接受两个 object 参数的重载方法,并且省去调用 ToString() 的必要。对于解释表达式编译器来说,这样做可能更高效,因为解释器的步骤较少。对于IL编译器来说,可能会略显低效(直接调用int.ToString()时不需要装箱,但是这种方式会进行装箱),但简化表达式的好处可能依然值得。 - Jon Hanna
1
@JonHanna 这确实是一种替代方案,但是你必须用 Expression.Convert(expr, typeof(object)) 将参数包装起来。 - Ivan Stoev
在我看来,字符串版本更好,但正如Jon所说,这取决于上下文。可以通过使用Expression.Call(expr, "ToString", Type.EmptyTypes)来简化ToString调用。 - Ivan Stoev
我可能会选择我觉得更方便的版本,直到它被证明是一个热点。如果我发现它在热点中,我会进行测量以确保,尽管我期望对象版本在UWP上下文中表现更好,而字符串版本在其他上下文中表现更好(UWP以不同方式编译表达式)。 - Jon Hanna
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接