请考虑以下代码:

private static void Main(string[] args)
{
    var ar = new double[]
    {
        100
    };

    FillTo(ref ar, 5);
    Console.WriteLine(string.Join(",", ar.Select(a => a.ToString()).ToArray()));
}

public static void FillTo(ref double[] dd, int N)
{
    if (dd.Length >= N)
        return;

    double[] Old = dd;
    double d = double.NaN;
    if (Old.Length > 0)
        d = Old[0];

    dd = new double[N];

    for (int i = 0; i < Old.Length; i++)
    {
        dd[N - Old.Length + i] = Old[i];
    }
    for (int i = 0; i < N - Old.Length; i++)
        dd[i] = d;
}

调试模式下的结果为:100、100、100、100、100. 但在释放模式下是:100,100,100,100,0.

发生了什么事?

它是用计算机测试的.NET framework 4.7.1和.NET核心2.0.0.

推荐答案

这似乎是一个JIT错误;我使用以下命令进行了测试:

// ... existing code unchanged
for (int i = 0; i < N - Old.Length; i++)
{
    // Console.WriteLine(i); // <== comment/uncomment this line
    dd[i] = d;
}

再加上Console.WriteLine(i)个就解决了这个问题.唯一的变化是:

// ...
L_0040: ldc.i4.0 
L_0041: stloc.3 
L_0042: br.s L_004d
L_0044: ldarg.0 
L_0045: ldind.ref 
L_0046: ldloc.3 
L_0047: ldloc.1 
L_0048: stelem.r8 
L_0049: ldloc.3 
L_004a: ldc.i4.1 
L_004b: add 
L_004c: stloc.3 
L_004d: ldloc.3 
L_004e: ldarg.1 
L_004f: ldloc.0 
L_0050: ldlen 
L_0051: conv.i4 
L_0052: sub 
L_0053: blt.s L_0044
L_0055: ret 

vs

// ...
L_0040: ldc.i4.0 
L_0041: stloc.3 
L_0042: br.s L_0053
L_0044: ldloc.3 
L_0045: call void [System.Console]System.Console::WriteLine(int32)
L_004a: ldarg.0 
L_004b: ldind.ref 
L_004c: ldloc.3 
L_004d: ldloc.1 
L_004e: stelem.r8 
L_004f: ldloc.3 
L_0050: ldc.i4.1 
L_0051: add 
L_0052: stloc.3 
L_0053: ldloc.3 
L_0054: ldarg.1 
L_0055: ldloc.0 
L_0056: ldlen 
L_0057: conv.i4 
L_0058: sub 
L_0059: blt.s L_0044
L_005b: ret 

这看起来完全正确(唯一的区别是额外的ldloc.3call void [System.Console]System.Console::WriteLine(int32),以及不同但相当于br.s的目标).

我想这需要一个即时修正.

环境:

  • Environment.Version:4.0.30319.42000
  • <TargetFramework>netcoreapp2.0</TargetFramework>
  • VS:15.5.0预览版5.0
  • dotnet --version: 2.1.1

.net相关问答推荐

删除数据库项目中的表

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

有没有更好的方法使用 Pusher Channels 的批事件发布消息?

EGC / 文本元素上的 .NET String.Split

dotnet ef dbcontext scaffold command --data-annotations 或 -d 命令行参数似乎不起作用

每当属性值发生变化时引发事件?

无法加载文件或程序集 Microsoft.Extensions.DependencyInjection.Abstractions,版本 = 1.1.0.0

为什么这个多态 C# 代码会打印它的功能?

代理、包装器或外观类之间有什么区别

序列化私有成员数据

如何将 NuGet 与 Visual C# Express 一起使用?

Await 运算符只能在 Async 方法中使用

参数命名:文件名还是文件名?

在 C# 中使用委托

返回 IList 是否比返回 T[] 或 List 更糟糕?

我应该如何删除 DbSet 中的所有元素?

如何将整个字符串与正则表达式匹配?

当它被抛出和捕获时,不要在那个异常处停止调试器

Dictionary.Add 与 Dictionary[key]=value 的区别

如何将我的应用程序窗口置于最前面?