我正在玩F#,并希望检查它与C#相比如何生成代码并找到一条奇怪的行。 我使用dotTrace来反编译代码并使C#等效。我还尝试使用LinqPad检查IL代码。
我的代码非常小。
open System
[<EntryPoint>]
let main argv =
let mutable sum = 0
// 1000 or 997
//let arr : int array = Array.zeroCreate 997
//let arr = Enumerable.Range(0, 997).ToArray()
let arr :int array = [|0..997|]
arr |> Array.iter (fun x -> sum <- sum + x)
printfn "%i" sum
0
这就是我得到的。
{
int func = 0;
int[] numArray = SeqModule.ToArray<int>(Operators.CreateSequence<int>(Operators.OperatorIntrinsics.RangeInt32(0, 1, 997)));
if ((object) numArray == null)
throw new ArgumentNullException("array");
int length = numArray.Length;
int index = 0;
int num1 = length - 1;
if (num1 >= index)
{
do
{
int num2 = numArray[index];
func += num2;
++index;
}
while (index != num1 + 1);
}
PrintfModule.PrintFormatLineToTextWriter<FSharpFunc<int, Unit>>(Console.Out, (PrintfFormat<FSharpFunc<int, Unit>, TextWriter, Unit, Unit>) new PrintfFormat<FSharpFunc<int, Unit>, TextWriter, Unit, Unit, int>("%i")).Invoke(func);
return 0;
}
}
这就是IL的样子。
// IL_0019: stloc.1 // 'numArray [Range(Instruction(IL_0019 stloc.1)-Instruction(IL_0040 ldloc.1))]'
// IL_001a: ldloc.1 // 'numArray [Range(Instruction(IL_0019 stloc.1)-Instruction(IL_0040 ldloc.1))]'
// IL_001b: box int32[]
// IL_0020: brfalse.s IL_0025
// IL_0022: nop
// IL_0023: br.s IL_0030
// IL_0025: ldstr "array"
// IL_002a: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string)
// IL_002f: throw
使用Release,.Net 4.6,FSharp.Core 4.4.0.0编译,优化代码,生成尾调用。
我对NULL检查和强制转换非常好奇。
(object) numArray == null
我明白为什么完成obj演员。该数组不是null,不能在没有。
的情况下进行检查我很好奇(不认为这是一个问题)而且问题更多的是关于编译器。