【发布时间】:2009-01-28 21:34:06
【问题描述】:
我正在通过反射器查看 String 和 Int32 类型,但找不到任何已定义的运算符。
如果没有定义,+/- 等如何作用于这些类型?
【问题讨论】:
我正在通过反射器查看 String 和 Int32 类型,但找不到任何已定义的运算符。
如果没有定义,+/- 等如何作用于这些类型?
【问题讨论】:
数字运算符是 IL 本身的一部分。不过,字符串上的“+”运算符有点特殊——它不是由字符串类型本身重载的,而是由编译器完成的。 C#编译器翻译:
string x = a + "hello" + b;
进入:
string x = string.Concat(a, "hello", b);
这比使用普通运算符完成连接更有效,因为否则每次连接都必须创建一个新字符串。
【讨论】:
String 类只有两个,它们具有符合 CLS 的名称:op_Equality 和 op_Inequality。编译器有很多关于 System.String 类的内置知识。为了能够使用 Ldstr 操作码,这是必要的。同样,它将 + 运算符转换为 String.Concat()。
Int32 的故事差不多,运算符和 IL 操作码之间存在直接匹配。
【讨论】:
原语的运算符很痛苦,正如我在尝试编写 generic support for operators 时发现的那样(即使用 T + T 等);还有一个讨论页here that covers this。
您可以通过使用诸如 Expression (.NET 3.5) 之类的抽象来解决此问题 - 否则,您将不得不查看原始 IL,或使用一些已知方法。
【讨论】:
Reflection.Emit和OpCodes.Add这样的东西; Expression 更容易使用 很多(或者只是从 MiscUtil 借用 Operator)。
是的,这些操作被转换为本地 IL 指令,而不是显式调用“operator+”方法。 它可能不是执行这些操作的托管代码...
【讨论】:
c# 编译器是一个疯狂的儿子......我曾经尝试重新创建 Nullable 类型的能力,但直到在他的博客上的一些评论中,Eric Lippert 向我保证它的能力也来自于编译器在遇到可空类型时生成。
【讨论】: