c#-4.0 – 可能的C#4.0编译错误,可以其他人验证吗?
既然我不知道这个错误触发了什么部分,那么我完全不知道如何更好地标记它.
这个问题是c# code seems to get optimized in an invalid way such that an object value becomes null问题的副产物,我试图在昨天晚上帮助Gary.他是一个发现有问题的人,我已经将问题简化为一个更简单的项目,并且在进一步了解之前需要验证,因此这里就是这个问题. 我会在Microsoft Connect上发布一个注释,如果其他人可以验证他们是否也遇到这个问题,当然我希望Jon,Mads或Eric也会看看它:) 它涉及: > 3个项目,其中2个是类库,其中一个是控制台程序(最后一个不需要重现问题,但只是执行这个显示问题,而您需要使用反射器并查看编译如果你不添加它的代码) 代码可在这里:code repository. 如果您想要让手变脏,我将在下面介绍如何制作项目的说明. 在返回一个简单的通用列表之前,在方法调用中产生一个无效的转换,这个问题就表现出来,在返回之前将其转换成一些奇怪的东西.原始代码最后一个转换为布尔值,是的,一个布尔值.编译器从List< SomeEntityObject>中添加了一个转换在布尔值返回结果之前,方法签名表示它将返回一个List< SomeEntityObject>.这反过来又导致运行时的奇怪问题,从方法调用的结果被认为是“优化掉”(原始问题)的一切,或与BadImageFormatException或InvalidProgramException或类似异常之一的崩溃. 在我的工作中重现这一点,我看到一个演员void [],现在我的代码的版本现在转换为一个TypedReference.在一种情况下,反射器崩溃,因此在这种情况下,代码最有可能超出希望.你的里程可能会有所不同. 以下是如何重现它: 注意:有可能会有更多的最小的形式,将重现的问题,但将所有的代码移动到一个项目,使其消失.从类中删除泛型也使问题消失.下面的代码重现了我每次的问题,所以我要离开它. 对于下面的代码中的转义的html字符,我对此表示歉意,这是Markdown对我的伎俩,如果有人知道如何纠正它,请让我知道,或者只是编辑问题 >为.NET 4.0创建一个包含控制台应用程序的新Visual Studio 2010解决方案 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; } } } >将一个新文件添加到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>(); } } } >在控制台项目中的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(); } } } >构建,并确保没有编译错误 public List<Dummy> GetDummies() { var policy = Cache.GetDefaultCacheItemPolicy(); return new List<Dummy>(); } 然而反射器说(对我来说,它可能会在你选择的投射中有所不同,反之亦然) 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; } 现在,这里有几件奇怪的事情,上面的崩溃/无效代码放在一边: > Library2,它具有Dummy.GetDummies,执行一个调用,以获得来自Library1的类上的默认缓存策略.它使用类型inference var policy = …,结果是一个CacheItemPolicy对象(代码中为空,但类型很重要). 但是,ClassLibrary2没有对System.Runtime.Caching的引用,所以不应该编译. 事实上,如果您在Dummy中注释了名为TryCommentingMeOut的方法,您将得到:
为什么有这样的方法使编译器很开心我不知道,我甚至不知道这是否与当前问题相关联.也许这是第二个bug. 解决方法
好的,我下载了你的代码,并且可以按照描述确认问题.
我没有做任何广泛的修补,但是当我跑步反射器一个发布版本似乎都OK(=空参考异常和干净的反汇编). 还有一个实验:我想知道使用CacheItemPolicies,所以我用自己的MyCacheItemPolicy(在第3个classlib中)替换它,并且弹出相同的BadImageFormat异常. 异常提到:{“坏二进制签名(来自HRESULT的异常:0x80131192)”} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |