该属性System.Runtime.CompilerServices.MethodImplAttribute
可用于向 JIT 编译器提供有关如何处理修饰方法的提示。特别是,该选项MethodImplOptions.AggressiveInlining
指示编译器在可能的情况下内联受影响的方法。不幸的是,F# 编译器在生成 IL 时似乎只是忽略了这个属性。
示例:以下 C# 代码
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Inc(int x) => x + 1;
被翻译成
.method public hidebysig static int32 Inc(int32 x) cil managed aggressiveinlining
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: add
IL_0003: ret
}
注意“aggressiveinlining”标志。
然而,这个 F# 代码
[<MethodImpl(MethodImplOptions.AggressiveInlining)>]
let inc x = x + 1
变成
.method public static int32 inc(int32 x) cil managed
{
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: ret
}
没有“积极的内联”。我还尝试将该属性应用于适当类的静态和非静态方法(type ...
),但结果是相同的。
但是,如果我将它应用于自定义索引器,就像这样
type Dummy =
member self.Item
with [<MethodImpl(MethodImplOptions.AggressiveInlining)>] get x = x + 1
得到的 IL 是
.method public hidebysig specialname instance int32 get_Item(int32 x) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.MethodImplAttribute::.ctor(valuetype [mscorlib]System.Runtime.CompilerServices.MethodImplOptions) = ( 01 00 00 01 00 00 00 00 )
.maxstack 8
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldc.i4.1
IL_0003: add
IL_0004: ret
}
...虽然我不确定这是否等同于 C# 编译器生成的“aggressiveinling”标志。
这种行为是期望/预期的吗?它是 F# 编译器中的错误吗?
(注意:我知道 F#inline
关键字,但这仅适用于我的库的 F# 客户端,而不适用于 C# 消费者。)