【问题标题】:Discovery of op_Addition OR implementing method for Expression.Add发现 op_Addition 或 Expression.Add 的实现方法
【发布时间】:2011-04-12 22:16:17
【问题描述】:

我正在使用 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 生成遵循 C# 规范 7.2.6.2 规定的积分提升规则的转换表达式(该语言将类似于 C#,但将与 JScript 交叉以及具有其他全新的关键字)。

当然,我继续测试字符串添加 - 即"a" + "b";,我得到了错误:

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

很公平 - 我反映了 System.String 并且确实没有定义该运算符。在这样的测试方法中生成表达式树:

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

表明确实创建了 Add BinaryExpression,但实现方法设置为 string.Concat 方法之一。

我知道在某些情况下我将不得不考虑做这样的事情,但是有多少其他类型以这种方式定义加法?只是string吗?

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

提前致谢!

【问题讨论】:

    标签: c# .net lambda antlr dynamic-languages


    【解决方案1】:

    看来我在回答自己的问题方面做得很好!

    抱歉,这个答案的格式可能更好,但我对 HTC 的渴望,它的键盘不支持所有符号!

    似乎没有办法在运行时“发现”这些规则,宿主语言有责任决定如何实现诸如字符串加法之类的事情。 C# 适应加法中的连续术语的数量,调用最适合匹配的 .Concat 方法。

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

    至于运算符的发现,Expression.Add 方法负责处理,但它不会自动执行任何转换,因此,与我在问题中引用的积分/浮点提升方法一样,它再次启动根据语言规则确定在尝试构建表达式之前是否需要进行其他转换。

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

    【讨论】:

      猜你喜欢
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 2014-09-07
      • 1970-01-01
      • 2012-03-29
      • 2020-03-11
      相关资源
      最近更新 更多