【问题标题】:Operation could destabilize the runtime?操作可能会破坏运行时的稳定性?
【发布时间】:2010-09-27 14:12:52
【问题描述】:

我有点难以理解这里的问题所在。我有一些代码使用 LINQ 从数据库中提取记录并将它们放入一个对象中,该对象被转换为一个接口。有点像这样:

public IEnumerable<ISomeObject> query()
{
    return from a in dc.SomeTable
           select new SomeObject
           {
             //Assign various members here
           } as ISomeObject;
}

当我对此进行测试时,我将返回的 IEnumerable 放入一个名为 results 的变量中并运行这一行:

Assert.AreEqual(EXPECTED_COUNT, results.Count());

当它运行时,我得到一个 System.Security.VerificationException: "Operation could destabilize the runtime."

我找到了解决方案here,是这样的:

var results = from a in dc.SomeTable
              select new SomeObject
              {
                //Assign various members here
              } as ISomeTable;
return results.OfType<ISomeObject>();

这可行,但我无法理解这里发生了什么。为什么我首先得到异常,上面的代码行是如何修复它的? MSDN 文档似乎表明这是一个类型安全问题,但我没有看到以前的代码在哪里是类型不安全的。

更新 我发现了更多信息。如果我将返回类型设为 IQueryable,则第一个示例有效。这让 what 出了点问题有了更多的了解,但我仍然对 why 感到困惑。为什么编译器不强制我将 IEnumerable 转换为 IQueryable?

【问题讨论】:

  • 当我将ANTS Performance Profiler 用于使用HtmlAgilityPack 的项目时,这种情况经常发生。对此的解决方案是通过将&lt;assemblyName&gt;HtmlAgilityPack&lt;/assemblyName&gt; 添加到文件“C:\Users\YourUserName\AppData\Local\Red Gate\ANTS Performance Profiler 9\LineLevelBlacklist.xml”来解决tell the profiler to exclude HtmlAgilityPack(用您的实际用户替换“YourUserName”名称)。

标签: c# .net linq linq-to-sql .net-3.5


【解决方案1】:

只是一个猜测,但 as 运算符可能返回 null - 因此它可能与 new SomeObject { ... } 代码的实际实现有关,因为它是语法糖。 return results.OfType&lt;ISomeTable&gt;(); 基于类型进行过滤,因此您的方法的 return 语句将仅返回该类型(确保类型安全)。我在返回泛型类型时遇到了类似的问题。

附:我喜欢“操作可能会破坏运行时的稳定性”。例外。这几乎就像“你可能会炸毁互联网”的例外。

【讨论】:

  • 猜对了,但事实并非如此。如果我进行 C 风格的转换,它也不起作用。
  • 德拉茨。我仍然认为问题在于您尝试返回的集合与方法的返回类型不一致。希望其他人知道:)
【解决方案2】:

如果你改变它仍然会失败:

select new SomeObject { ... } as ISomeTable;

到这里:

select (ISomeTable) new SomeObject { ... };

?

如果是这样(我看到您已经确认),也许这与接口实现可以是类或结构这一事实有关?如果转换为抽象类而不是接口,问题是否仍然存在?

【讨论】:

    【解决方案3】:

    我认为这是this forum post 指出的协变或逆变问题。

    在 Eric Lippert 的博客上查看 Covariance and Contravariance in C#, Part Two: Array CovarianceCovariance and Contravariance series 的其余部分。

    虽然他在我链接的文章中处理数组,但我相信这里会出现类似的问题。在您的第一个示例中,您将返回一个 IEnumerable,其中可能包含实现比 ISomeTable 更大的接口的对象(即 - 当 IEnumerable 可以时,您可以将 Turtle 放入 Animals IEnumerable只包含长颈鹿)。我认为当您返回 IQueryable 时它起作用的原因是因为它比您可以返回的任何东西都更大/更宽,所以你可以保证你返回的东西你将能够处理(?) .

    在第二个示例中,OfType 确保返回的是一个对象,该对象存储了仅返回可以转换为 Giraffe 的那些元素所需的所有信息。

    我很确定这与上述类型安全问题有关,但正如 Eric Lippert 所说 Higher Order Functions Hurt My Brain,我无法准确表达为什么这是一个协变/逆变问题。

    【讨论】:

    • 这听起来不错。我可以看到你从哪里来,无法表达为什么会这样。我再等等看有没有人有更直接的解释,否则我会接受这个答案。
    【解决方案4】:

    我猜,Linq to Sql 在翻译成 sql 语句时可能不支持强制转换。

    【讨论】:

    • 这根本不是真的。有效的示例也涉及强制转换。
    • 我上面的回答意味着,它可能不支持使用语法转换。但它允许使用 OfType。 SomeObject 是否实现接口 ISomeObject?
    【解决方案5】:

    我发现 OfType 在使用 linq to sql 时有一些令人讨厌的副作用。例如,之前在对 db 运行查询后评估的部分 linq 被转换为 SQL。这失败了,因为这些部分没有等效的 SQL。我最终改用了 .Cast ,这似乎也解决了这个问题。

    【讨论】:

      【解决方案6】:

      我在寻找自己的“操作可能会破坏运行时”的解决方案时发现了这个条目。虽然上面的协方差/反方差建议看起来很有趣,但最后我发现在打开代码覆盖并设置 AllowPartiallyTrustedCallers 程序集属性的情况下运行单元测试会得到相同的错误消息。

      删除 AllowPartiallyTrustedCallers 属性使我的测试运行良好。我还可以关闭代码覆盖以使它们运行,但这不是一个可接受的解决方案。

      希望这可以帮助访问此页面的其他人尝试找到解决此问题的方法。

      【讨论】:

      • 这是我的问题,但它是 AllowPartiallyTrustedCallers 设置在被测程序集引用的程序集上。微软肯定需要解决这个问题,因为我需要在我的程序集中使用该标志,为什么在正常上下文中运行的代码不会导致测试导致问题?! “测试模仿真实代码调用它”发生了什么?!显然测试主机正在做一些特殊的事情来导致问题。
      • 刚刚收到完全相同的错误消息,这确实是问题所在。删除 AllowPartiallyTrustedCallers 属性让我的测试运行得很好。
      • 这对我也有用。我切换到 VS 2012,突然我的 Tao Open GL 库不再工作了。这解决了它。
      • 我们在寻找“操作可能破坏运行时稳定”的答案时也遇到了这个问题......这可能是修复,但在框架 dll 内部(Microsoft.VisualStudio.QualityTools.UnitTestFramework 等) .为了帮助被 MS 在 .Net 4.0 到 4.5 更新中引入的这个框架错误捕获的任何其他人,有一个通过 Windows 更新(或特别是 support.microsoft.com/kb/2748645)提供的修补程序可以纠正这个问题(如果您的代码在更新前工作)跨度>
      【解决方案7】:

      我用类似的代码遇到了这个错误;

      IEnumerable<Table> records = (from t in db.Tables
                                    where t.Id.Equals(1)
                                    select t).ToList();
      

      这个看似无害的代码是从 Page 调用的 UserControl 方法的一部分。在 .NET4 开发环境中没有问题,但是,当站点被预编译并部署到 .NET3.5 上的服务器时,我得到了这个错误。

      我怀疑这与控件被编译为单独的 DLL 以及框架之间的安全更改(如 this .NET security blog 中所述)有关。

      我的解决方案:在 .NET4 上运行实时站点

      【讨论】:

        【解决方案8】:

        在我的例子中,我错误地在 Linq2SQL 类的 Column 属性中声明了 Storage 属性

            [Column(Storage = "_Alias", DbType = "NVarChar(50)")]
            public string UserAlias
        

        【讨论】:

          【解决方案9】:

          我有同样的问题,但继承 我在程序集 A 中定义了一个类,在程序集 B 中定义了一个子类 在我将以下属性添加到程序集 A 后,问题解决了:

          [assembly: SecurityRules(SecurityRuleSet.Level1, SkipVerificationInFullTrust = true)]
          

          【讨论】:

            【解决方案10】:

            我在使用“动态数据访问框架”Passive library 时遇到了这个错误。错误的来源是 DynamicDatabase.cs 文件中的第 100 行。

            databaseDetectors = (databaseDetectors ?? Enumerable.Empty<DatabaseDetector>()).DefaultIfEmpty(new DatabaseDetector());
            

            我把那行代码改成:

            databaseDetectors = (databaseDetectors ?? Enumerable.Empty<DatabaseDetector>()).DefaultIfEmpty(new DatabaseDetector()).OfType<IDatabaseDetector>();
            

            这样做解决了问题。我继续forked the project 并将更改提交给原作者。

            感谢 Jason Baker 在您最初的问题中指出解决方案。

            附带说明,原始库在我的本地计算机和 Rackspace VPS 上运行良好,但是当我将相同的代码推送到共享托管环境(GoDaddy 和 Rackspace 的云站点)时,我开始收到“操作可以破坏运行时”错误。

            【讨论】:

              【解决方案11】:

              `我已经添加到 web.config 文件中的 System.Security.VerificationException 部分:“操作可能会破坏运行时的稳定性。”不来找我。

              <system.Web>
              <trust level="Full"/>
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2010-12-25
                • 1970-01-01
                • 2012-09-15
                • 1970-01-01
                • 2014-12-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多