gpt4 book ai didi

c# - 2013 和 2015 调试编译之间的匿名方法静态性不同

转载 作者:太空狗 更新时间:2023-10-29 20:39:03 25 4
gpt4 key购买 nike

我希望有人可以识别导致以下程序行为发生变化的语言功能(或错误)。它是从一个更大的场景中复制的,如果提供给 Orchard::Go 的委托(delegate)不是静态的,该场景旨在记录一条消息。

using System;

namespace Sample
{
public static class Program
{
public static void Main()
{
new Apple();
}
}

public sealed class Apple
{
public Apple()
{
Orchard.Go(() => { });
}
}

internal static class Orchard
{
public static void Go(Action action)
{
Console.WriteLine(action.Method.IsStatic);
}
}
}

场景是:

  • 如果我编译并运行使用 Visual Studio 2013 生成的调试 版本,输出为True
  • 如果我编译并运行使用 Visual Studio 2015 生成的调试 版本,输出为False
  • 在这两种情况下,目标 .NET Framework 都是 4.5。
  • 如果我编译并运行使用 Visual Studio 2015 生成的release 版本,输出为 True(因此与 Visual Studio 2013 一致)。
  • Visual Studio 2015 是 RC 版本(如果重要的话)。

我可以从 ildasm 看到 2013 生成的代码...


___[MOD] C:\Sample.exe
| M A N I F E S T
|___[NSP] Sample
| |___[CLS] Sample.Apple
| | | .class public auto ansi sealed beforefieldinit
| | |___[STF] CS$9__CachedAnonymousMethodDelegate1 : private static class [mscorlib]System.Action
| | |___[MET] .ctor : void()
| | | b__0 : void()
| |
| |___[CLS] Sample.Orchard
| | | .class private abstract auto ansi sealed beforefieldinit
| | |___[STM] Go : void(class [mscorlib]System.Action)
| |
| |___[CLS] Sample.Program
| | | .class public abstract auto ansi sealed beforefieldinit
| | |___[STM] Main : void()
| |
|

...与 2015 年生成的代码明显不同...


___[MOD] C:\Sample.exe
| M A N I F E S T
|___[NSP] Sample
| |___[CLS] Sample.Apple
| | | .class public auto ansi sealed beforefieldinit
| | |___[CLS] c
| | | | .class nested private auto ansi serializable sealed beforefieldinit
| | | | .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) ...
| | | |___[STF] 9 : public static initonly class Sample.Apple/'c'
| | | |___[STF] 9__0_0 : public static class [mscorlib]System.Action
| | | |___[STM] .cctor : void()
| | | |___[MET] .ctor : void()
| | | | b__0_0 : void()
| | |
| | |___[MET] .ctor : void()
| |
| |___[CLS] Sample.Orchard
| | | .class private abstract auto ansi sealed beforefieldinit
| | |___[STM] Go : void(class [mscorlib]System.Action)
| |
| |___[CLS] Sample.Program
| | | .class public abstract auto ansi sealed beforefieldinit
| | |___[STM] Main : void()
| |
|

...但我对 IL 和编译器更改的了解不足以确定这是新功能还是意外错误。我可以根据要求生成完整的 IL 转储,但是任何人都可以根据我提供的信息告诉我这里发生了什么以及它是否是故意的?为什么匿名方法在 2013 年被认为是静态的,但在 2015 年被认为是非静态的?

最佳答案

我将此问题记录为 Microsoft Connect 票证 here并提供了对 C# 规范的引用,该规范确认您不能依赖匿名方法的封闭类型的任何特定实现。具体来说,

6.5.1/2 "The invocation list of a delegate produced from an anonymous function contains a single entry. The exact target object and target method of the delegate are unspecified. In particular, it is unspecified whether the target object of the delegate is null, the this value of the enclosing function member, or some other object."

Microsoft Connect 票证也链接到类似的问题 here如果有人感兴趣。因此,就我而言,具体而言,编译器似乎“按预期工作”,而我的问题的解决方案是“不那样做”。

关于c# - 2013 和 2015 调试编译之间的匿名方法静态性不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30906720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com