jjzjj

c# - 将 Enumerable.ToDictionary 与扩展方法一起使用时为 "CLR detected an Invalid Program"

coder 2024-05-23 原文

一位同事向我传递了一个有趣的代码示例,该示例在运行时因 InvalidProgramException(“CLR 检测到无效程序”)而崩溃。

这个问题似乎发生在 JIT 时间,因为它编译得很好,但就在调用带有“违规”行的方法之前抛出异常 - 我猜是因为它正在被 JIT。

有问题的行是调用 Enumerable.ToDictionary 并将 Func 作为第二个参数传递。

如果 Func 参数完全用 lambda 指定,它就可以工作;如果指定为方法组,如果失败。这两者一定是等价的吧?

这让我(以及发现它的同事!)感到难过 - 这看起来确实像是一个 JIT 错误。

[编辑:抱歉 - 我在代码示例中以错误的方式得到了通过和失败的情况 - 现在已更正(上面的描述是正确的)]

谁有解释吗?

using System;
using System.Linq;

internal class Program
{
    private static void Main(string[] args)
    {
        Test.Try();
    }
}

public class Test
{
    public static readonly int[] integers = new[] { 1, 3, 5 };
    public static void Try()
    {
        var line = new Line { A = 3, B = 5 };

        // PASSES
        var dict = integers.ToDictionary<int, int, decimal>(i => i, i => line.Compute(i));

        // FAILS
        //var dict = integers.ToDictionary<int, int, decimal>(i => i, line.Compute);

        Console.WriteLine(string.Join(" ", dict.Select(kv => kv.Key + "-" + kv.Value)));
    }
}

public class Line
{
    public decimal A;
    public decimal B;
}

public static class SimpleCompute
{
    public static decimal Compute(this Line line, int value)
    {
        return line.A*value + line.B;
    }
}

最佳答案

编译器错误。

有关信息,我有异步 CTP,这可能是相关的; csc 报告:4.0.30319.440

似乎是之间的区别:

public static void TryTwo() // fails
{
    var line = new Line {A = 3, B = 5};

    var dict = integers.ToDictionary<int, int, decimal>(i => i, line.Compute);
    Console.WriteLine("TryTwo complete");
}
public static void TryFive() // works
{
    var line = new Line { A = 3, B = 5 };

    Func<int, decimal> func = line.Compute;
    var dict = integers.ToDictionary<int, int, decimal>(i => i, func);
    Console.WriteLine("TryFour complete");
}

让我们看看反射器:

.method public hidebysig static void TryTwo() cil managed
{
    .maxstack 4
    .locals init (
        [0] class Line <>g__initLocal6)
    L_0000: newobj instance void Line::.ctor()
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: ldc.i4.3 
    L_0008: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
    L_000d: stfld valuetype [mscorlib]System.Decimal Line::A
    L_0012: ldloc.0 
    L_0013: ldc.i4.5 
    L_0014: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
    L_0019: stfld valuetype [mscorlib]System.Decimal Line::B
    L_001e: ldsfld int32[] Test::integers
    L_0023: ldsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegate8
    L_0028: brtrue.s L_003b
    L_002a: ldnull 
    L_002b: ldftn int32 Test::<TryTwo>b__7(int32)
    L_0031: newobj instance void [mscorlib]System.Func`2<int32, int32>::.ctor(object, native int)
    L_0036: stsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegate8
    L_003b: ldsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegate8
    L_0040: call class [mscorlib]System.Collections.Generic.Dictionary`2<!!1, !!2> [System.Core]System.Linq.Enumerable::ToDictionary<int32, int32, valuetype [mscorlib]System.Decimal>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, !!1>, class [mscorlib]System.Func`2<!!0, !!2>)
    L_0045: pop 
    L_0046: ldstr "TryTwo complete"
    L_004b: call void [mscorlib]System.Console::WriteLine(string)
    L_0050: ret 
}

对比

 .method public hidebysig static void TryFive() cil managed
{
    .maxstack 4
    .locals init (
        [0] class Line line,
        [1] class [mscorlib]System.Func`2<int32, valuetype [mscorlib]System.Decimal> func,
        [2] class Line <>g__initLocal9)
    L_0000: newobj instance void Line::.ctor()
    L_0005: stloc.2 
    L_0006: ldloc.2 
    L_0007: ldc.i4.3 
    L_0008: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
    L_000d: stfld valuetype [mscorlib]System.Decimal Line::A
    L_0012: ldloc.2 
    L_0013: ldc.i4.5 
    L_0014: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
    L_0019: stfld valuetype [mscorlib]System.Decimal Line::B
    L_001e: ldloc.2 
    L_001f: stloc.0 
    L_0020: ldloc.0 
    L_0021: ldftn valuetype [mscorlib]System.Decimal SimpleCompute::Compute(class Line, int32)
    L_0027: newobj instance void [mscorlib]System.Func`2<int32, valuetype [mscorlib]System.Decimal>::.ctor(object, native int)
    L_002c: stloc.1 
    L_002d: ldsfld int32[] Test::integers
    L_0032: ldsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegateb
    L_0037: brtrue.s L_004a
    L_0039: ldnull 
    L_003a: ldftn int32 Test::<TryFive>b__a(int32)
    L_0040: newobj instance void [mscorlib]System.Func`2<int32, int32>::.ctor(object, native int)
    L_0045: stsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegateb
    L_004a: ldsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegateb
    L_004f: ldloc.1 
    L_0050: call class [mscorlib]System.Collections.Generic.Dictionary`2<!!1, !!2> [System.Core]System.Linq.Enumerable::ToDictionary<int32, int32, valuetype [mscorlib]System.Decimal>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, !!1>, class [mscorlib]System.Func`2<!!0, !!2>)
    L_0055: pop 
    L_0056: ldstr "TryFour complete"
    L_005b: call void [mscorlib]System.Console::WriteLine(string)
    L_0060: ret 
}

如果您查看损坏的版本,它只加载一个委托(delegate)。编译器错误,基本上:

L_0023: ldsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegate8
L_0028: brtrue.s L_003b
L_002a: ldnull 
L_002b: ldftn int32 Test::<TryTwo>b__7(int32)
L_0031: newobj instance void [mscorlib]System.Func`2<int32, int32>::.ctor(object, native int)
L_0036: stsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegate8
L_003b: ldsfld class [mscorlib]System.Func`2<int32, int32> Test::CS$<>9__CachedAnonymousMethodDelegate8
L_0040: call class [mscorlib]System.Collections.Generic.Dictionary`2<!!1, !!2> [System.Core]System.Linq.Enumerable::ToDictionary<int32, int32, valuetype [mscorlib]System.Decimal>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [mscorlib]System.Func`2<!!0, !!1>, class [mscorlib]System.Func`2<!!0, !!2>)

以上都是“检查缓存的i => i是否存在;如果不存在,则加载它”。它对第二个委托(delegate)从不做任何事情。因此,堆栈上没有足够的值来进行方法调用。

关于c# - 将 Enumerable.ToDictionary 与扩展方法一起使用时为 "CLR detected an Invalid Program",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9292663/

有关c# - 将 Enumerable.ToDictionary 与扩展方法一起使用时为 "CLR detected an Invalid Program"的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  6. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  7. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  8. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  9. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  10. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

随机推荐