• LambdaParser:解析代码字符串为Lambda表达式并编译为委托


    最近没事写了这个解析代码字符串为Lambda表达式并编译为委托的模块:LambdaParser。

    介绍

    先举个最简单的例子让大家明白LambdaParser模块究竟做什么:

    Delegate dele = ExpressionParser.Compile("(int m)=>-m");
    var result
    = (int)dele.DynamicInvoke(10); // result = -10

    简单的说,LambdaParser模块就是在运行时编译Lambda表达式

    原理

    LambdaParser的最主要方法Compile接受一个代码字符串,返回一个委托。
    LambdaParser会分析输入的代码字符串,然后一个一个构造Lambda Expression,最后编译成委托。
    这样,我们就能动态编译并执行代码

    特点

    在运行时编译Lambda表达式不是一个常规解决方案,但有时候很有用,它比反射更灵活(可直接编写代码语句),更快(编译后的委托可缓存起来),更易懂(只是动态构造代码)。

    一些说明

    1.基于Lambda表达式,所以当然也不支持Lambda表达式不支持的,如:赋值操作等。

    2.只支持Lambda表达式,不支持Lambda语句。也就是说不能写多条Lambda语句,所以if,for,while等肯定是不支持的。

    3.理所当然,支持数字运算,支持字符串拼接。目前尚未做编译优化,比如:1+2这种常量运算本来是可以在编译的时候就计算出来,但现在是原原本本的编译出来,在运行时去计算。字符串的拼接也一样。

    4.目前尚不支持checked运算。

    5.由于我是看了老赵的《这下没理由嫌Eval的性能差了吧?》才有这想法的,对于那一段Expression代码(DynamicPropertyAccessor构造函数),当时花了N+M次的来回阅读,才勉强弄明白意思,于是计划写这个,所以我用老赵的思路也实现了一个FastEval,由于我这个类库本来就是做解析的,所以对于FastEval的参数也就原生的支持表达式语句,而不仅仅是属性名,所以我认为我这个FastEval实现比原本的Eval更快,更灵活:)
    example:<%#FastEval("Sex?\"男\":\"女\"")%>

    6.本打算同样用老赵的思想实现FastReflectionLib,但发现LambdaParser还有很多事要做,就先搁置。

    7.如果本身的Lambda表达式写得有问题,那么报的错误可能会很奇怪,因为时间原因目前没有很友好的错误提示。

    结束语

    项目中必定会有不少bug,若是解析某个特定code时出意外,希望将输出的code发给我,可以在这里回复,或者发到我邮箱:zhucai+lambdaparser@gmail.com
    今天只是简单介绍一下其功能及使用方法,之后有时间我再来详细谈谈设计过程。
    项目地址:http://code.google.com/p/lambda-parser/
    贴上所有已通过的测试用例,方便弄明白用法:

    [TestClass()]
    public class ExpressionParserTest
    {
    /// <summary>
    /// 数字运算
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Number()
    {
    {
    var expected
    = ExpressionParser.Compile("(int m,int n)=>m*n").DynamicInvoke(3, 8);
    var actual
    = 3 * 8;

    Assert.AreEqual(expected, actual);
    }
    {
    var expected
    = ExpressionParser.Compile("(int m,int n,double l)=>l/m*n").DynamicInvoke(3, 8, 24.46);
    var actual
    = 24.46 / 3 * 8;

    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>1+2-3*4/2+20%7;";
    int expected = 1 + 2 - 3 * 4 / 2 + 20 % 7;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    // 在无参数的情况下可以省略()=>
    string code = "2 + 3 * 4 / 2 - 4 % (2 + 1) + 32 - 43 * (6 - 4) + 3.3";
    double expected = 2 + 3 * 4 / 2 - 4 % (2 + 1) + 32 - 43 * (6 - 4) + 3.3;

    Func
    <double> func = ExpressionParser.Compile<Func<double>>(code);
    double actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "2 + 3 * 4 / 2 - 4 % (2.4 + 1) + 32 - 43 * (6 - 4) + 3.3 * (322 / (43 - (3 - 1)))";
    double expected = 2 + 3 * 4 / 2 - 4 % (2.4 + 1) + 32 - 43 * (6 - 4) + 3.3 * (322 / (43 - (3 - 1)));

    Func
    <double> func = ExpressionParser.Compile<Func<double>>(code);
    double actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "3.32 * 12d + 34L - 12d";
    double expected = 3.32 * 12d + 34L - 12d;

    Func
    <double> func = ExpressionParser.Compile<Func<double>>(code);
    double actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    // number+string
    Func<int, string> f = ExpressionParser.Compile<Func<int, string>>(
    "m=>2+m.ToString(\"000\")");
    string expected = f(2); // "2002"
    Assert.AreEqual(expected, "2002");
    }
    {
    int m = 10;
    var expected
    = -m;

    Delegate dele
    = ExpressionParser.Compile("(int m)=>-m");
    var actual
    = dele.DynamicInvoke(10);

    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 字符串拼接和函数调用
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_StringAdd()
    {
    string code = "2.ToString()+3+(4*2)";
    string expected = "238";

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code);

    string actual = func();

    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 成员访问,方法调用,构造函数(传参)
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Member_Method_Ctor()
    {
    string code = "()=>new Test_Zhucai.LambdaParser.TestClass(9,2).Member1";
    string code2 = "()=>new Test_Zhucai.LambdaParser.TestClass(){Member1 = 5,Member2 = 4}.GetMemberAll()";

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    Func
    <int> func2 = ExpressionParser.Compile<Func<int>>(code2);

    int actual = func();
    int actual2 = func2();

    Assert.AreEqual(actual, actual2);
    }
    /// <summary>
    /// 委托传多个参数
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_MultiLambdaParam()
    {
    string code = "(m,n,l)=>m+n+l"; // m:1 n:2 l:"3"
    string expected = "33";

    Func
    <int, int, string, string> func = ExpressionParser.Compile<Func<int, int, string, string>>(code);
    string actual = func(1, 2, "3");
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 泛型类
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Generic()
    {
    {
    string code = "()=>typeof(List<string>).FullName";
    var expected
    = typeof(List<string>).FullName;

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code, "System", "System.Collections.Generic");
    var actual
    = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>typeof(List<List<string>>).FullName";
    var expected
    = typeof(List<List<string>>).FullName;

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code, "System", "System.Collections.Generic");
    var actual
    = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 泛型类
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_GenericList()
    {
    {
    string code = "(m)=>new List<string>(){ Capacity = m * 3 }.Capacity";
    var expected
    = new List<string>() { Capacity = 3 * 3 }.Capacity;

    Func
    <int, int> func = ExpressionParser.Compile<Func<int, int>>(code, "System", "System.Collections.Generic");
    var actual
    = func(3);
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>new List<string>(){ \"abc\",\"def\" }[1]";
    var expected
    = new List<string>() { "abc", "def" }[1];

    var actual
    = ExpressionParser.Compile(code, "System", "System.Collections.Generic").DynamicInvoke();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试Nullable
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Nullable()
    {
    {
    Delegate dele
    = ExpressionParser.Compile("(int? m)=>m==null");
    var actual
    = dele.DynamicInvoke((int?)null);

    Assert.AreEqual(
    true, actual);
    }
    {
    Delegate dele
    = ExpressionParser.Compile("(int?)null");
    var actual
    = dele.DynamicInvoke();

    Assert.AreEqual(
    null, null);
    }
    {
    Delegate dele
    = ExpressionParser.Compile("new System.Nullable<int>(10).Value - 3");
    Nullable
    <int> actual = (Nullable<int>)dele.DynamicInvoke();

    Assert.AreEqual(
    7, actual);
    }
    {
    Delegate dele
    = ExpressionParser.Compile("new long?(10L).Value - 3");
    long? actual = (long?)dele.DynamicInvoke();

    Assert.AreEqual(
    7, actual);
    }
    }
    /// <summary>
    /// new数组,数组访问
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Array()
    {
    string code = "()=>new string[]{\"aa\",\"bb\"}[1]";
    string expected = "bb";

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code);
    string actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// new数组,数组访问2
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Array2()
    {
    string code = "()=>new string[5].Length";
    int expected = 5;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    //[TestMethod]
    //public void ParseDelegateTest_ListInit()
    //{
    // string code = "()=>new List<string>().Count";
    // var expected = new List<string>().Count;

    // Func<string> func = ExpressionParser.Compile<Func<string>>(code,"System");
    // string actual = func();
    // Assert.AreEqual(expected, actual);
    //}
    /// <summary>
    /// new多维数组
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_ArrayMultiRank()
    {
    string code = "()=>new string[5,4].Rank";
    int expected = 2;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 索引器访问
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Indexer()
    {
    string code = "m=>(string)m[1]";
    string expected = "bb";

    Func
    <ArrayList, string> func = ExpressionParser.Compile<Func<ArrayList, string>>(code);
    string actual = func(new ArrayList(new string[] { "aa", "bb" }));
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 重复生成
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Repeater()
    {
    string code = "m=>(string)m[1]";
    string expected = "bb";

    Func
    <ArrayList, string> func = ExpressionParser.Compile<Func<ArrayList, string>>(code);
    func
    = ExpressionParser.Compile<Func<ArrayList, string>>(code);
    string actual = func(new ArrayList(new string[] { "aa", "bb" }));
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 成员初始化
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_MemberInit()
    {
    string code = "()=>new Test_Zhucai.LambdaParser.TestClass(){Member1 = 20}.ToString()";
    string expected = "20";

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code);
    string actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符typeof,sizeof
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorTypeofSizeof()
    {
    string code = "()=>typeof(string).FullName+sizeof(int)";
    string expected = typeof(string).FullName + sizeof(int);

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code);
    string actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符!
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorNot()
    {
    string code = "(m)=>!m";
    bool expected = true;

    Func
    <bool, bool> func = ExpressionParser.Compile<Func<bool, bool>>(code);
    bool actual = func(false);
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符~
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorBitNot()
    {
    string code = "()=>~9";
    int expected = ~9;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符convert()
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorConvert()
    {
    string code = "()=>(int)(9.8+3.3)";
    int expected = (int)(9.8 + 3.3);

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符>>,<<
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorBitShift()
    {
    string code = "()=>(9>>3)-(5<<2)";
    int expected = (9 >> 3) - (5 << 2);

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符>
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorGreaterThan()
    {
    {
    string code = "()=>9>2";
    bool expected = (9 > 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2>9";
    bool expected = (2 > 9);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2>2";
    bool expected = (2 > 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符<
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorLessThan()
    {
    {
    string code = "()=>9<2";
    bool expected = (9 < 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2<9";
    bool expected = (2 < 9);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2<2";
    bool expected = (2 < 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符<=
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorLessThanOrEqual()
    {
    {
    string code = "()=>9<=2";
    bool expected = (9 <= 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2<=2";
    bool expected = (2 <= 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2<=9";
    bool expected = (2 <= 9);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符>=
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorGreaterThanOrEqual()
    {
    {
    string code = "()=>9>=2";
    bool expected = (9 >= 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2>=2";
    bool expected = (2 >= 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2>=9";
    bool expected = (2 >= 9);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符==
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorEqual()
    {
    {
    string code = "()=>9==2";
    bool expected = (9 == 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2==2";
    bool expected = (2 == 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2==9";
    bool expected = (2 == 9);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符!=
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorNotEqual()
    {
    {
    string code = "()=>9!=2";
    bool expected = (9 != 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2!=2";
    bool expected = (2 != 2);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>2!=9";
    bool expected = (2 != 9);

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符is
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorIs()
    {
    {
    string code = "(m)=>((object)m) is int";
    bool expected = ((object)2) is int;

    Func
    <object, bool> func = ExpressionParser.Compile<Func<object, bool>>(code);
    bool actual = func(2);
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>((object)\"abc\") is int";
    bool expected = ((object)"abc") is int;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符as
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorAs()
    {
    {
    string code = "(m)=>((object)m) as string";
    string expected = ((object)2) as string;

    Func
    <object, string> func = ExpressionParser.Compile<Func<object, string>>(code);
    string actual = func(2);
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>((object)\"abc\") as string";
    string expected = ((object)"abc") as string;

    Func
    <string> func = ExpressionParser.Compile<Func<string>>(code);
    string actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符^
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorExclusiveOr()
    {
    string code = "()=>3^7";
    int expected = 3 ^ 7;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符&
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorAnd()
    {
    string code = "()=>3&7";
    int expected = 3 & 7;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符|
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorOr()
    {
    string code = "()=>3|7";
    int expected = 3 | 7;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试操作符&&
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorAndAlso()
    {
    {
    string code = "()=>true&&false";
    bool expected = true && false;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>true&&true";
    bool expected = true && true;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>false && false";
    bool expected = false && false;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符||
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorOrElse()
    {
    {
    string code = "()=>true||false";
    bool expected = true || false;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>true||true";
    bool expected = true || true;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>false||false";
    bool expected = false || false;

    Func
    <bool> func = ExpressionParser.Compile<Func<bool>>(code);
    bool actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符?:
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorCondition()
    {
    {
    string code = "()=>1==1?1:2";
    int expected = 1 == 1 ? 1 : 2;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = "()=>1==2?1:2";
    int expected = 1 == 2 ? 1 : 2;

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    /// <summary>
    /// 测试操作符??
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_OperatorDoubleQuestionMark()
    {
    string code = "(m)=>m??\"bb\"";
    string expected = "aa";

    Func
    <string, string> func = ExpressionParser.Compile<Func<string, string>>(code);
    string actual = func("aa");
    Assert.AreEqual(expected, actual);

    // use code to test 2
    expected = "bb";
    actual
    = func(null);
    Assert.AreEqual(expected, actual);
    }
    /// <summary>
    /// 测试namespace
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Namespace()
    {
    string code = "new TestClass().Member1";
    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code, typeof(TestClass).Namespace);
    int actual = func();
    Assert.AreEqual(
    0, actual);
    }
    /// <summary>
    /// 测试默认实例
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_DefaultInstance()
    {
    {
    string code = "Member1*2";
    Func
    <TestClass, int> func = ExpressionParser.Compile<Func<TestClass, int>>(code, true);
    int actual = func(new TestClass(13, 13));
    Assert.AreEqual(
    13 * 2, actual);
    }
    {
    string code = "Member1 == 13";
    Delegate func
    = ExpressionParser.Compile(code, typeof(TestClass));
    var actual
    = func.DynamicInvoke(new TestClass(13, 13));
    Assert.AreEqual(
    true, actual);
    }
    {
    string code = "m=>Member1*m.Member2";
    Func
    <TestClass, TestClass, int> func = ExpressionParser.Compile<Func<TestClass, TestClass, int>>(code, true);
    int actual = func(new TestClass(13, 13), new TestClass(23, 23));
    Assert.AreEqual(
    13 * 23, actual);
    }
    }
    /// <summary>
    /// 测试Exec方法
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_DefaultExec()
    {
    object obj = new { Name = "zhangsan", Id = 18 };
    {
    object actual = obj.E("Id");

    Assert.AreEqual(
    18, actual);
    }
    {
    int actual = obj.E<int>("Id");

    Assert.AreEqual(
    18, actual);
    }
    {
    string actual = obj.E<string>("Name + Id");

    Assert.AreEqual(
    "zhangsan18", actual);
    }
    {
    object obj2 = new { Name = "李四", Id = 18 };
    object obj3 = new { Name = "王五", Id = 18 };
    string actual = obj.E<string>("$0.Name + $1.Name + $2.Name", obj2, obj3);

    Assert.AreEqual(
    "zhangsan李四王五", actual);
    }
    {
    object obj2 = new { Name = "李四", Id = 18 };
    string actual = obj.E<string>("Name + $1.Name", obj2);

    Assert.AreEqual(
    "zhangsan李四", actual);
    }
    {
    object obj2 = new TestClass(2, 3);
    int actual = obj2.E<int>("GetMemberAll()");

    Assert.AreEqual(
    5, actual);
    }
    }

    /// <summary>
    /// 测试一个复杂代码
    /// </summary>
    [TestMethod]
    public void ParseDelegateTest_Other()
    {
    {
    string code = @"()=>new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1 = 3
    }.Member1 == 3 ? new Test_Zhucai.LambdaParser.TestClass[]
    {
    new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1 = 3
    }
    }[4-4].Member1 + 3 * new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2 = 5
    }.Member2 : new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2 = 5,
    Member1 = 9,
    }.GetMemberAll();
    ";
    int expected = new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1
    = 3
    }.Member1
    == 3 ? new Test_Zhucai.LambdaParser.TestClass[]
    {
    new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1
    = 3
    }
    }[
    4 - 4].Member1 + 3 * new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2
    = 5
    }.Member2 :
    new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2
    = 5,
    Member1
    = 9,
    }.GetMemberAll();

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    {
    string code = @"()=>new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1 = 3
    }.Member1 != 3 ? new Test_Zhucai.LambdaParser.TestClass[]
    {
    new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1 = 3
    }
    }[new Test_Zhucai.LambdaParser.TestClass().Member1].Member1 + 3 * new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2 = 5
    }.Member2 : new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2 = 5,
    Member1 = 9,
    }.GetMemberAll();
    ";
    int expected = new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1
    = 3
    }.Member1
    != 3 ? new Test_Zhucai.LambdaParser.TestClass[]
    {
    new Test_Zhucai.LambdaParser.TestClass()
    {
    Member1
    = 3
    }
    }[
    new Test_Zhucai.LambdaParser.TestClass().Member1].Member1 + 3 * new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2
    = 5
    }.Member2 :
    new Test_Zhucai.LambdaParser.TestClass()
    {
    Member2
    = 5,
    Member1
    = 9,
    }.GetMemberAll();

    Func
    <int> func = ExpressionParser.Compile<Func<int>>(code);
    int actual = func();
    Assert.AreEqual(expected, actual);
    }
    }
    }

    public class TestClass
    {
    public int Member1 { get; set; }
    public int Member2;
    public TestClass()
    {
    }
    public TestClass(int member, int member2)
    {
    this.Member1 = member;
    this.Member2 = member2;
    }
    public int GetMemberAll()
    {
    return this.Member1 + this.Member2;
    }
    public override string ToString()
    {
    return Member1.ToString();
    }
    }

    转载需注明出处:http://cnblogs.com/zhucai/

    我的微博:http://weibo.com/zhucai

  • 相关阅读:
    Delphi接口
    delphi cxgrid导出excel去除货币符号
    DelphiXE4- System.IOUtils.TDirectory笔记查询后缀名为dll的文件
    Kivy中文显示
    AppDomain与进程、线程、Assembly之间关系
    Attributes(2): Displaying attributes for a class.(显示类属性)
    Attributes(2): Displaying attributes for a class.(显示类属性)
    Attributes(1):反射Attribute并输出
    大数据乘法
    Qt中利用QDomDocument读写xml小Demo
  • 原文地址:https://www.cnblogs.com/zhucai/p/LambdaParser_Lambda_Expression_Parser.html
Copyright © 2020-2023  润新知