所以我稍微看了一下MethodImpl 属性 http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimplattribute(v=vs.110).aspx我遇到了MethodImplOptions.AggressiveInlined http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.methodimploptions%28v=VS.110%29.aspx其描述为:
如果可能的话,应该内联该方法。
哦哦,我心想,这听起来很有趣 - 我可以假装我比编译器更聪明,并仅使用我邪恶意志的力量和几个方括号强制内联代码,哈,哈,哈......
因此,我启动了Visual Studio 2013,创建了一个控制台应用程序,将.NET版本设置为4.5.1,并编写了程序来结束所有程序(将其编译为Release
当然是模式):
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
public static class SoHelpful
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetSomeValueProbablyTwelve()
{
return 12;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int GetSomeValueLikelyThirteen()
{
return 13;
}
public static int GetSomeValueMaybeItIsTwentyEight()
{
return 29;
}
}
class Program
{
static void Main()
{
int twelve = SoHelpful.GetSomeValueProbablyTwelve();
int thirteen = SoHelpful.GetSomeValueLikelyThirteen();
int twentyNine = SoHelpful.GetSomeValueMaybeItIsTwentyEight();
Console.WriteLine((twelve + thirteen + twentyNine));
}
}
}
现在,如果我快速执行 ildasm,我会看到以下内容:
.class public abstract auto ansi sealed beforefieldinit ConsoleApplication1.SoHelpful
extends [mscorlib]System.Object
{
.method public hidebysig static int32 GetSomeValueProbablyTwelve() cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldc.i4.s 12
IL_0002: ret
} // end of method SoHelpful::GetSomeValueProbablyTwelve
.method public hidebysig static int32 GetSomeValueLikelyThirteen() cil managed noinlining
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldc.i4.s 13
IL_0002: ret
} // end of method SoHelpful::GetSomeValueLikelyThirteen
.method public hidebysig static int32 GetSomeValueMaybeItIsTwentyEight() cil managed
{
// Code size 3 (0x3)
.maxstack 8
IL_0000: ldc.i4.s 29
IL_0002: ret
} // end of method SoHelpful::GetSomeValueMaybeItIsTwentyEight
} // end of class ConsoleApplication1.SoHelpful
.class private auto ansi beforefieldinit ConsoleApplication1.Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 29 (0x1d)
.maxstack 2
.locals init ([0] int32 twelve,
[1] int32 thirteen,
[2] int32 twentyNine)
IL_0000: call int32 ConsoleApplication1.SoHelpful::GetSomeValueProbablyTwelve()
IL_0005: stloc.0
IL_0006: call int32 ConsoleApplication1.SoHelpful::GetSomeValueLikelyThirteen()
IL_000b: stloc.1
IL_000c: call int32 ConsoleApplication1.SoHelpful::GetSomeValueMaybeItIsTwentyEight()
IL_0011: stloc.2
IL_0012: ldloc.0
IL_0013: ldloc.1
IL_0014: add
IL_0015: ldloc.2
IL_0016: add
IL_0017: call void [mscorlib]System.Console::WriteLine(int32)
IL_001c: ret
} // end of method Program::Main
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
} // end of class ConsoleApplication1.Program
有趣的是,所以定义了三个方法:
.method public hidebysig static int32 GetSomeValueLikelyThirteen() cil managed noinlining
.method public hidebysig static int32 GetSomeValueProbablyTwelve() cil managed
.method public hidebysig static int32 GetSomeValueMaybeItIsTwentyEight() cil managed
因此,看起来我的侵略性内联属性已经丢失了。
我可以看到noinlining
on GetSomeValueLikelyThirteen
but GetSomeValueProbablyTwelve
and GetSomeValueMaybeItIsTwentyEight
是相同的。
那么到底发生了什么?我想有以下几种可能:
- C# 编译器已经意识到
GetSomeValueProbablyTwelve
只是无法内联,所以不会用我愚蠢的属性来麻烦 JIT。
- C# 编译器已经意识到
GetSomeValueMaybeItIsTwentyEight
可以内联,这就是为什么它在 IL 中与GetSomeValueProbablyTwelve
(所以在这种情况下我的归因在很大程度上是毫无意义和愚蠢的)。
- 有一些编译设置或我必须调整才能使属性被识别。
- 它没有实施于
C#
at all.
- 我发现了一个错误
- 其他的东西
那么,有人知道它是什么吗?