c#-4.0 – 可能的C#4.0编译错误,可以其他人验证吗?

前端之家收集整理的这篇文章主要介绍了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解决方
>添加两个新项目,两个类库,也是.NET 4.0(我将假定他们被命名为ClassLibrary1和ClassLibrary2)
>调整所有项目以使用完整的.NET 4.0运行时,而不仅仅是客户端配置文件
>在控制台项目中添加一个引用到ClassLibrary2
>将ClassLibrary2中的引用添加到ClassLibrary 1
>删除默认添加到类库的两个Class1.cs文件
>在ClassLibrary1中,添加对System.Runtime.Caching的引用
>将一个新文件添加到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;
        }
    }
}

>将一个新文件添加到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();
        }
    }
}

>构建,并确保没有编译错误
>现在尝试运行程序.这应该是一个更可怕的例外.我看到了InvalidProgramException和BadImageFormatException,具体取决于最终的转换
>查看反射器中生成的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的方法,您将得到:

The type ‘System.Runtime.Caching.CacheItemPolicy’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Runtime.Caching,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a’.

为什么有这样的方法使编译器很开心我不知道,我甚至不知道这是否与当前问题相关联.也许这是第二个bug.
> DummyCache中有一个类似的方法,如果您在Dummy中还原方法,以便代码再次编译,然后注释掉DummyCache中的方法,该方法在其上方有“Try commenting this out”注释,您将得到相同的编译器错误

解决方法

好的,我下载了你的代码,并且可以按照描述确认问题.

我没有做任何广泛的修补,但是当我跑步反射器一个发布版本似乎都OK(=空参考异常和干净的反汇编).
反射器(6.10.11)在Debug版本上崩溃.

还有一个实验:我想知道使用CacheItemPolicies,所以我用自己的MyCacheItemPolicy(在第3个classlib中)替换它,并且弹出相同的BadImageFormat异常.

异常提到:{“坏二进制签名(来自HRESULT的异常:0x80131192)”}

猜你在找的C#相关文章