【问题标题】:Fun with delegate casting -> InvalidProgramException委托铸造的乐趣-> InvalidProgramException
【发布时间】:2011-03-09 08:24:27
【问题描述】:

我遇到了一个有趣的问题,请看下面的代码。

class Program
{
    static void Main(string[] args)
    {        
        var testDelegate = (System.Delegate)(Action)(() =>
        {
            Console.WriteLine("Hey!");
        });
    }
}

这按预期工作(什么都不做,因为我们不调用任何东西),但现在将“(动作)”替换为“新动作”,看看会发生什么:

class Program
{
    static void Main(string[] args)
    {
        var testDelegate = (System.Delegate)new Action(() =>
        {
            Console.WriteLine("Hey!");
        });
    }
}

它编译得很好,但是当我尝试运行它时,我得到一个“InvalidProgramException”。关于为什么会发生这种情况的任何想法?

编辑

这是 DEBUG 版本,发布版本没有显示同样的问题。

主要的IL:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       3 (0x3)
  .maxstack  0
  .locals init ([0] class [mscorlib]System.Delegate testDelegate)
  IL_0000:  nop
  IL_0001:  stloc.0
  IL_0002:  ret
} // end of method Program::Main

代表的IL:

.method private hidebysig static void  '<Main>b__0'() cil managed
{
  .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldstr      "Hey!"
  IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_000b:  nop
  IL_000c:  ret
} // end of method Program::'<Main>b__0'

【问题讨论】:

  • 无法重现,没想到。你确定样品是正确的吗?如果是这样,您能否提供更多信息(框架版本等)?
  • 上面的代码工作得很好......
  • @Ani 在 Visual Studio 2008 sp1,Target Framework 3.5 中完成。我已经能够在两台不同的机器上重现这一点,一台 Win XP 和一台 Win7。 (不过 vs2008 的安装是一样的)...
  • 您能否使用 ildasm 包含为 Main 生成的 IL?我认为这个示例代码没有任何问题。
  • @Peter Huene:我已经发布了 IL。

标签: c# visual-studio-2008-sp1


【解决方案1】:

如果为 Main 生成的 IL 准确无误,则看起来像 C# 编译器错误。 Main 中 IL_0001 处的指令会从评估堆栈中弹出一些不存在的内容。 JIT 编译器注意到这一点,并在 Main 被 JIT 编译时引发 InvalidProgramException。

编辑:我猜这是您遇到的编译器错误:http://connect.microsoft.com/VisualStudio/feedback/details/371711/invalidprogramexception-c-compiler-3-5

【讨论】:

  • 更不用说 maxstack 是 0。不幸的是,我没有 VS 2008 SP1 来看看我是否可以重现这个。
  • @M$:EPIC 在we won't be able to get to get to this fix for the next version of Visual Studio 上失败。
  • @Mehrdad:由于我的笔记本电脑只有一个虚拟机上的 Windows 并且虚拟机没有安装 VS,我无法确认它是否在 2010 年得到解决。通常一个被接受的连接错误会为分配的开发人员生成足够多的唠叨电子邮件,以便在问题得到解决后正确关闭它。作为一名前 Microsoft 开发人员,我必须说,由于发布周期漫长、繁琐,无法快速解决客户问题让我抓狂。
  • @Peter Huene:嗯,一定是这样。感谢您找到它!我从没想过我会在我的生活中偶然发现 C# 的编译器错误:o。无论如何,这里是用 3.5 编译器编译它的命令行: "C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\ v3.5\System.Core.dll" /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /out:invalidProg2.exe /target:exe Program.cs"
  • @Peter:嗯,有趣...是的,我想它也会让我发疯。这听起来并不有趣,听到人们抱怨某事但无法及时解决……尤其是当人们没有意识到这并不是你的错时。 :\
猜你喜欢
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 2010-12-24
  • 2013-11-26
  • 1970-01-01
  • 1970-01-01
  • 2012-07-08
  • 1970-01-01
相关资源
最近更新 更多