gpt4 book ai didi

c# - 操作可能会破坏运行时的稳定性?

转载 作者:IT王子 更新时间:2023-10-29 04:01:26 28 4
gpt4 key购买 nike

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

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,则第一个示例有效。这更清楚地说明了什么出了问题,但我仍然对原因感到困惑。为什么编译器不强制我将 IEnumerable 转换为 IQueryable?

最佳答案

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

参见 Covariance and Contravariance in C#, Part Two: Array Covariance和其余的Covariance and Contravariance series在 Eric Lippert 的博客上。

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

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

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

关于c# - 操作可能会破坏运行时的稳定性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/378895/

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