簡體   English   中英

String.IndexOf 方法的表達式樹

[英]Expression tree for String.IndexOf method

我應該如何為string.IndexOf("substring", StringComparison.OrdinalIgnoreCase)構造表達式樹?

我可以讓它在沒有第二個參數的情況下工作: 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參數,我可以讓它工作。

謝謝

我懷疑有兩個問題。

第一個是你獲取方法的方式——你要求一個只有一個字符串參數的方法,而不是一個有兩個參數的方法:

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

第二個是您提供的- 它應該是常量的實際值,而不是字符串:

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"));
    }
}

最簡單的方法是通過 lambda 獲得它,如下所示:

//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"));

這比手動構建表達式樹更具可讀性和可維護性。

我一直對直接投入手動構建表達式樹的人數感到驚訝。 不需要什么時候可以讓編譯器為您完成工作。

我沒有檢查它的 rest,但如果只有枚舉會出現問題:

Expression.Constant(StringComparison.OrdinalIgnoreCase)

或者

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

而且你有更多的選擇。 或者在這里查看我的答案。

編輯:忘記括號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM