8

の式ツリーをどのように構築する必要がありstring.IndexOf("substring", StringComparison.OrdinalIgnoreCase)ますか?

2番目の引数なしで動作させることができます:StringComparison.OrdinalIgnoreCase。これまでの私の試みは次のとおりです。

var methodCall = typeof (string).GetMethod("IndexOf", new[] {typeof (string)});
Expression[] parms = new Expression[]{right, Expression.Constant("StringComparison.OrdinalIgnoreCase", typeof (Enum))};
var exp =  Expression.Call(left, methodCall, parms);
return exp;

またこれを試しました:

var methodCall = typeof (string).GetMethod(method, new[] {typeof (string)});
Expression[] parms = new Expression[]{right, Expression.Parameter(typeof(Enum) , "StringComparison.OrdinalIgnoreCase")};
var exp =  Expression.Call(left, methodCall, parms);
return exp;

パラメータを無視すると動作するようになることを覚えておいてくださいOrdinalIgnoreCase

ありがとう

4

3 に答える 3

12

2つの問題があると思います。

1つ目は、メソッドを取得する方法です。2つのパラメーターを持つメソッドではなく、1つの文字列パラメーターのみを持つメソッドを要求しています。

var methodCall = typeof (string).GetMethod("IndexOf",
                            new[] { typeof (string), typeof(StringComparison) });

2つ目は、指定するです。文字列ではなく、定数の実際の値である必要があります。

Expression[] parms = new Expression[] { right, 
    Expression.Constant(StringComparison.OrdinalIgnoreCase) };

編集:これが完全な作業サンプルです:

using System;
using System.Linq.Expressions;

class Test
{
    static void Main()
    {
        var method = typeof (string).GetMethod("IndexOf",
                new[] { typeof (string), typeof(StringComparison) });

        var left = Expression.Parameter(typeof(string), "left");
        var right = Expression.Parameter(typeof(string), "right");

        Expression[] parms = new Expression[] { right, 
                Expression.Constant(StringComparison.OrdinalIgnoreCase) };

        var call = Expression.Call(left, method, parms);
        var lambda = Expression.Lambda<Func<string, string, int>>
            (call, left, right);

        var compiled = lambda.Compile();
        Console.WriteLine(compiled.Invoke("hello THERE", "lo t"));
    }
}
于 2011-08-17T07:32:18.400 に答える
3

これを行う最も簡単な方法は、次のようなラムダを介して取得することです。

//the compiler will convert the lambda into an expression
Expression<Func<string, string, int>> expression = (s1, s2) => s1.IndexOf(s2, StringComparison.OrdinalIgnoreCase);
//compile the expression so we can call it
var func = expression.Compile();
//outputs 2
Console.WriteLine(func("Case Sensitive", "se sensitive"));

これは、式ツリーを手動で作成するよりもはるかに読みやすく、保守しやすいものです。

手動で式ツリーを作成することに真っ直ぐ飛び込む人の数には常に驚いています。コンパイラに作業を任せることができる時期は必要ありません。

于 2011-08-17T09:13:42.880 に答える
0

残りの部分はチェックしませんでしたが、列挙型だけが問題を引き起こす場合は次のようになります。

Expression.Constant(StringComparison.OrdinalIgnoreCase)

また

Expression.Constant(Enum.Parse(typeof(StringComparison), "OrdinalIgnoreCase"), typeof(Enum));

そして、より多くのオプションがあります。または、ここで私の答えを確認してください。

編集:paranthesisを忘れました。

于 2011-08-17T07:34:41.417 に答える