代码之家  ›  专栏  ›  技术社区  ›  Andras Zoltan

opu加法的发现或实现方法表达式。添加

  •  2
  • Andras Zoltan  · 技术社区  · 14 年前

    我正在用Antlr和表达式树写一种语言。

    我已经为我的树解析器定义了一个标准的工厂方法,在生成加法时可以使用它,对于内置的整型类型,它的工作非常好,现在我将继续讨论更一般的类型。

    目前它非常幼稚,它只是这样做(进行中的TDD代码通常看起来很幼稚,对吧!):

    protected Expression GenerateAdd(Expression left, Expression right)
    {
      if (left.Type.Equals(right.Type))
        return Expression.Add(left, right);
      if (left.Type.IsValueType && right.Type.IsValueType)
        Promote7_2_6_2(ref left, ref right);
      return Expression.Add(left, right);
    }
    

    在哪里? Promote7_2_6_2

    很自然,我开始测试字符串加法。 "a" + "b";

    System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'.

    很公平-我想系统字符串确实没有定义运算符。在测试方法中生成表达式树,如下所示:

    Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;
    

    显示确实创建了Add BinaryExpression,但将实现方法设置为 string.Concat 方法。

    string

    它是嵌入在C编译器中的规则吗?还是有某种可发现的元数据,我可以用来在其他类型上自动发现此类方法?

    提前谢谢!

    1 回复  |  直到 14 年前
        1
  •  1
  •   Andras Zoltan    14 年前

    似乎我在回答我自己的问题时做得很好!

    我的道歉,这个答案可以更好的格式,但我对我的宏达电的愿望和它的键盘不支持所有的符号!

    因此,如果我希望我的语言支持在没有定义操作符的情况下添加类实例,例如,我可以简单地编写或找到一个静态方法来完成(当然是正确的签名!)然后用硬连线的语言在这种情况下使用它。这里的一个典型例子是是否通过静态数组方法支持array1+array2。

    至于发现运营商表达式。添加方法处理这个问题,但它不会自动执行任何转换,因此,与我在问题中引用的整型/浮点提升方法一样,在尝试构建表达式之前,还是要根据语言规则来确定是否需要其他转换。

    因此,最好先反映运算符,看看是否为这两种类型定义了一个运算符,然后再考虑是否存在转换。