ang*_*son 10 compiler-bug c#-4.0
由于我不确切地知道触发错误的确切部分,我不完全确定如何更好地标记它.
这个问题是SO问题的副产品c#代码似乎以无效方式优化,使得对象值变为null,我试图在昨天晚上帮助Gary.他是那个发现存在问题的人,我只是将问题简化为一个更简单的项目,并且在我进一步研究之前需要验证,因此这里有这个问题.
如果其他人可以验证他们是否也遇到了这个问题,我会发布一条关于Microsoft Connect的说明,当然我希望Jon,Mads或Eric也会看一下它:)
它涉及:
代码可在此处获得:代码库.
如果您想亲自动手,我会在下面发布如何制作项目的说明.
该问题通过在方法调用中生成无效的强制转换,在返回一个简单的泛型列表,在返回之前将其转换为奇怪的东西来展示自身.最初的代码最后是一个强制转换为布尔值,是的,一个布尔值.List<SomeEntityObject>在返回结果之前,编译器从a添加了一个强制转换,并且方法签名表示它将返回一个List<SomeEntityObject>.这反过来又导致在运行时奇怪的问题,一切从方法调用的结果被认为是"优化掉"(原题),或一方崩溃BadImageFormatException或者InvalidProgramException或类似的例外之一.
在我重现这个的过程中,我看到了一个void[]强制转换器,我的代码的当前版本现在被转换为TypedReference.在一个案例中,Reflector崩溃,因此在这种情况下,代码很可能超出了希望.您的里程可能有所不同
以下是重现它的方法:
注意:可能有更多的最小形式可以重现问题,但将所有代码移动到一个项目使其消失.从类中删除泛型也会使问题消失.下面的代码每次都为我重现问题,所以我将它保留原样.
我为下面代码中的转义html字符道歉,这是Markdown对我玩耍的技巧,如果有人知道如何纠正它,请让我知道,或者只是编辑问题
将新文件添加到ClassLibrary1,将其命名为DummyCache.cs,并粘贴以下代码:
using System;
using System.Collections.Generic;
using System.Runtime.Caching;
namespace ClassLibrary1
{
public class DummyCache<TModel> where TModel : new()
{
public void TriggerMethod<T>()
{
}
// Try commenting this out, note that it is never called!
public void TriggerMethod<T>(T value, CacheItemPolicy policy)
{
}
public CacheItemPolicy GetDefaultCacheItemPolicy()
{
return null;
}
public CacheItemPolicy GetDefaultCacheItemPolicy(IEnumerable<string> dependentKeys, bool createInsertDependency = false)
{
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)将新文件添加到ClassLibrary2,将其命名为Dummy.cs并粘贴以下代码:
using System;
using System.Collections.Generic;
using ClassLibrary1;
namespace ClassLibrary2
{
public class Dummy
{
private DummyCache<Dummy> Cache { get; set; }
public void TryCommentingMeOut()
{
Cache.TriggerMethod<Dummy>();
}
public List<Dummy> GetDummies()
{
var policy = Cache.GetDefaultCacheItemPolicy();
return new List<Dummy>();
}
}
}
Run Code Online (Sandbox Code Playgroud)粘贴到控制台项目的Program.cs中的以下代码中:
using System;
using System.Collections.Generic;
using ClassLibrary2;
namespace ConsoleApplication23
{
class Program
{
static void Main(string[] args)
{
Dummy dummy = new Dummy();
// This will crash with InvalidProgramException
// or BadImageFormatException, or a similar exception
List<Dummy> dummies = dummy.GetDummies();
}
}
}
Run Code Online (Sandbox Code Playgroud)构建,并确保没有编译器错误
查看Reflector中生成的Dummy.GetDummies代码.源代码如下所示:
public List<Dummy> GetDummies()
{
var policy = Cache.GetDefaultCacheItemPolicy();
return new List<Dummy>();
}
Run Code Online (Sandbox Code Playgroud)
反射器说(对我来说,它可能会因为它为你选择的投射而有所不同,并且在一种情况下反射器甚至崩溃):
public List<Dummy> GetDummies()
{
List<Dummy> policy = (List<Dummy>)this.Cache.GetDefaultCacheItemPolicy();
TypedReference CS$1$0000 = (TypedReference) new List<Dummy>();
return (List<Dummy>) CS$1$0000;
}
Run Code Online (Sandbox Code Playgroud)现在,这里有几个奇怪的事情,上面的崩溃/无效代码:
Library2 Dummy.GetDummies执行调用以从Library1获取类的默认缓存策略.它使用类型推断var policy = ...,结果是一个CacheItemPolicy对象(代码中为null,但类型很重要).
但是,ClassLibrary2没有对System.Runtime.Caching的引用,因此不应该编译.
事实上,如果你在Dummy中注释掉名为的方法TryCommentingMeOut,你会得到:
"System.Runtime.Caching.CacheItemPolicy"类型在未引用的程序集中定义.您必须添加对程序集'System.Runtime.Caching,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'的引用.
为什么让这个方法存在让编译器开心我不知道,我甚至不知道这是否与当前问题有关.也许这是第二个错误.
有一个类似的方法DummyCache,如果你恢复方法Dummy,以便代码再次编译,然后注释掉该方法,DummyCache其上面有"试着评论出来"注释,你得到相同的编译器错误
好的,我下载了您的代码,可以按照描述确认问题。
我没有对此进行任何广泛的修改,但是当我运行&反射器发布构建时,一切似乎都正常(= null ref 异常和干净的反汇编)。
Reflector (6.10.11) 在调试版本中崩溃。
还有一个实验:我想知道 CacheItemPolicies 的使用,因此我将其替换为我自己的 MyCacheItemPolicy(在第三类库中),并且弹出了相同的 BadImageFormat 异常。
异常提到:{“错误的二进制签名。(来自 HRESULT 的异常:0x80131192)”}
| 归档时间: |
|
| 查看次数: |
891 次 |
| 最近记录: |