C# 操作会破坏运行时的稳定性吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/378895/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Operation could destabilize the runtime?
提问by Jason Baker
I'm having a little bit of trouble understanding what the problem is here. I have a bit of code that pulls records from a database using LINQ and puts them into an object which is cast into an interface. It looks a bit like this:
我在理解这里的问题时遇到了一些麻烦。我有一些代码使用 LINQ 从数据库中提取记录并将它们放入一个对象中,该对象被转换为一个接口。它看起来有点像这样:
public IEnumerable<ISomeObject> query()
{
return from a in dc.SomeTable
select new SomeObject
{
//Assign various members here
} as ISomeObject;
}
When I test this, I put the returned IEnumerable into a variable called results and run this line:
当我对此进行测试时,我将返回的 IEnumerable 放入一个名为 results 的变量中并运行以下行:
Assert.AreEqual(EXPECTED_COUNT, results.Count());
When this is run, I get a System.Security.VerificationException: "Operation could destabilize the runtime."
运行时,我收到 System.Security.VerificationException:“操作可能会破坏运行时的稳定性。”
I found the solution here, which is this:
我在这里找到了解决方案,这是这样的:
var results = from a in dc.SomeTable
select new SomeObject
{
//Assign various members here
} as ISomeTable;
return results.OfType<ISomeObject>();
This works, but I'm having trouble understanding what's happening here. Why did I get the exception in the first place and how did the lines of code above fix it? The MSDN documentation seems to suggest that this is an issue of type safety, but I'm not seeing where the previous code was type-unsafe.
这有效,但我无法理解这里发生的事情。为什么我首先得到异常,上面的代码行是如何修复它的?MSDN 文档似乎表明这是一个类型安全问题,但我没有看到以前的代码在哪里类型不安全。
UPDATEA little bit more information I found out. The first example works if I make the return type IQueryable. This sheds a little bit more light on whatwas going wrong, but I'm still confused about the why. Why didn't the compiler force me to cast the IEnumerable into an IQueryable?
更新我发现的更多信息。如果我将返回类型设为 IQueryable,则第一个示例有效。这更清楚地说明出了什么问题,但我仍然对原因感到困惑。为什么编译器不强迫我将 IEnumerable 转换为 IQueryable?
采纳答案by Grant Wagner
I believe it is an issue of covariance or contravariance as noted by this forum post.
我相信这是一个协变或逆变的问题,正如本论坛帖子所指出的那样。
See Covariance and Contravariance in C#, Part Two: Array Covarianceand the rest of the Covariance and Contravariance seriesat Eric Lippert's blog.
请参见 Eric Lippert 的博客中的 C# 中的协方差和逆变,第二部分:数组协方差和协方差和逆变系列的其余部分。
Although he is dealing with Arrays in the article I linked, I believe a similar problem presents itself here. With your first example, you are returning an IEnumerable
that could contain objects that implement an interface that is largerthan ISomeTable
(i.e. - you could put a Turtle into an Animals IEnumerable when that IEnumerable can only contain Giraffes). I think the reason it works when you return IQueryable
is because that is larger/widerthan anything you could return, so you're guaranteed that what you return you will be able to handle(?).
尽管他在我链接的文章中处理数组,但我相信这里也存在类似的问题。有了您的第一个例子,你是返回一个IEnumerable
可能包含实现一个接口,对象较大的比ISomeTable
(即-你可以把龟到动物的IEnumerable时IEnumerable的只能包含长颈鹿)。我认为它在您返回时起作用的原因IQueryable
是因为它比您可以返回的任何东西都大/宽,因此您可以保证您返回的东西将能够处理(?)。
In the second example, OfTypeis ensuring that what gets returned is an object that stores all the information necessary to return only those elements that can be cast to Giraffe.
在第二个示例中,OfType确保返回的是一个对象,该对象存储仅返回可转换为 Giraffe 的那些元素所需的所有信息。
I'm pretty sure it has something to do with the issues of type safety outlined above, but as Eric Lippert says Higher Order Functions Hurt My Brainand I am having trouble expressing precisely why this is a co/contravariant issue.
我很确定它与上面概述的类型安全问题有关,但是正如 Eric Lippert 所说的高阶函数伤害了我的大脑,我无法准确表达为什么这是一个协变/逆变问题。
回答by Zachary Yates
Just a guess, but the asoperator may return a null - so it may have to do with the actual implementation of the new SomeObject { ... }
code, since it's syntactic sugar. The return results.OfType<ISomeTable>();
filters based on type, so your method's return statement will only return that type (ensuring type safety). I've run into a similar issue with returning generic types.
只是一个猜测,但as运算符可能会返回一个 null - 所以它可能与new SomeObject { ... }
代码的实际实现有关,因为它是语法糖。在return results.OfType<ISomeTable>();
基于类型的过滤器,让你的方法的return语句将只返回类型(确保类型安全)。我在返回泛型类型时遇到了类似的问题。
P.S. I love the "Operation could destabilize the runtime." exception. That's almost like the "You might blow up the internet" exception.
PS 我喜欢“操作可能会破坏运行时的稳定性”。例外。这几乎就像“你可能会炸毁互联网”例外。
回答by Av Pinzur
Does it still fail if you change this:
如果你改变它,它是否仍然失败:
select new SomeObject { ... } as ISomeTable;
to this:
对此:
select (ISomeTable) new SomeObject { ... };
?
?
If so (as I see you've confirmed), perhaps this has to do with the fact that an interface implementation could be either a class or a struct? Does the problem still appear if you cast to an abstract class rather than an interface?
如果是这样(正如我看到您已经确认的那样),也许这与接口实现可以是类或结构这一事实有关?如果您转换为抽象类而不是接口,问题是否仍然出现?
回答by Chaowlert Chaisrichalermpol
I guess, Linq to Sql may not support casting when translate to sql statement.
我猜,当转换为 sql 语句时,Linq to Sql 可能不支持强制转换。
回答by LaserJesus
I found that OfType had some nasty side effects when using linq to sql. For example, parts of the linq that were previously evaluated after the query was run against the db were instead translated to SQL. This failed as those sections had no SQL equivalent. I ended up using .Cast instead which seems to solve the problem as well.
我发现 OfType 在使用 linq to sql 时有一些令人讨厌的副作用。例如,在针对 db 运行查询之后先前评估的 linq 部分被转换为 SQL。这失败了,因为这些部分没有 SQL 等效项。我最终使用 .Cast 代替,这似乎也解决了问题。
回答by Ira Miller
I found this entry while looking for my own solution to "operation could destabilize the runtime". While the covariance/contra-variance advice above looks very interesting, in the end I found that I get the same error message by running my unit tests with code coverage turned on and the AllowPartiallyTrustedCallers assembly attribute set.
我在寻找我自己的“操作可能会破坏运行时”的解决方案时发现了这个条目。虽然上面的协方差/逆方差建议看起来很有趣,但最后我发现通过在打开代码覆盖率和 AllowPartiallyTrustedCallers 程序集属性的情况下运行我的单元测试,我得到了相同的错误消息。
Removing the AllowPartiallyTrustedCallers attribute caused my tests to run fine.I could also turn off code coverage to make them run but that was not an acceptable solution.
删除 AllowPartiallyTrustedCallers 属性使我的测试运行良好。我也可以关闭代码覆盖率以使它们运行,但这不是一个可接受的解决方案。
Hopefully this helps someone else who makes it to this page trying to find a solution to this issue.
希望这有助于其他人进入此页面并尝试找到此问题的解决方案。
回答by Red Taz
I came across this error with similar code;
我用类似的代码遇到了这个错误;
IEnumerable<Table> records = (from t in db.Tables
where t.Id.Equals(1)
select t).ToList();
This seemingly harmless code was part of a UserControl method which was called from a Page. No problem in a .NET4 development environment, however, when the site was PreCompiled and deployed to the server on .NET3.5 I got this error.
这个看似无害的代码是从 Page 调用的 UserControl 方法的一部分。在 .NET4 开发环境中没有问题,但是,当站点被预编译并部署到 .NET3.5 上的服务器时,我收到了这个错误。
I suspect this has something to do with the fact that the control was being compiled into a separate DLL combined with the security changes between the frameworks as described in this .NET security blog
我怀疑这与以下事实有关,即控件被编译成一个单独的 DLL,并结合了.NET 安全博客中描述的框架之间的安全更改
My solution: run the live site on .NET4
我的解决方案:在 .NET4 上运行实时站点
回答by user1760527
In my case i had wrongly declared the Storage property in the Column attribute of a Linq2SQL class
就我而言,我错误地在 Linq2SQL 类的 Column 属性中声明了 Storage 属性
[Column(Storage = "_Alias", DbType = "NVarChar(50)")]
public string UserAlias
回答by Homayoun Behzadian
I had same problem, but with inheritance I defined a class in assembly A and a subclass in Assembly B after I added below attribute to assembly A, problem solved:
我有同样的问题,但是通过继承,我在程序集 A 中定义了一个类,在程序集 A 中定义了一个子类,然后将以下属性添加到程序集 A,问题解决了:
[assembly: SecurityRules(SecurityRuleSet.Level1, SkipVerificationInFullTrust = true)]
回答by Tod Birdsall
I ran into this error while using the "Dynamic data access framework" Passive library. The source of the error was line 100 in the DynamicDatabase.cs file.
我在使用“动态数据访问框架”被动库时遇到了这个错误。错误的来源是 DynamicDatabase.cs 文件中的第 100 行。
databaseDetectors = (databaseDetectors ?? Enumerable.Empty<DatabaseDetector>()).DefaultIfEmpty(new DatabaseDetector());
I changed that line of code to:
我将该行代码更改为:
databaseDetectors = (databaseDetectors ?? Enumerable.Empty<DatabaseDetector>()).DefaultIfEmpty(new DatabaseDetector()).OfType<IDatabaseDetector>();
Doing so resolved the problem. I went ahead and forked the projectand submitted the change to the original author.
这样做解决了问题。我继续将项目分叉并将更改提交给原作者。
Thank you, Jason Baker, for pointing out the solution in your original question.
谢谢你,杰森贝克,在你的原始问题中指出解决方案。
On a side note, the original library ran fine on my local machine and on a Rackspace VPS, but when I pushed the same code to a shared hosting environment (GoDaddy and Rackspace's Cloud Sites), I began getting the "Operation could destabilize the runtime" error.
附带说明一下,原始库在我的本地机器和 Rackspace VPS 上运行良好,但是当我将相同的代码推送到共享托管环境(GoDaddy 和 Rackspace 的云站点)时,我开始收到“操作可能会破坏运行时的稳定性” “ 错误。