可能的C#4.0编译错误,可以别人验证吗? [英] Possible C# 4.0 compiler error, can others verify?

查看:353
本文介绍了可能的C#4.0编译错误,可以别人验证吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因为我不知道究竟是什么部分触发错误,我不完全确定如何更好地标记它。

Since I don't know exactly what part of it alone that triggers the error, I'm not entirely sure how to better label it.

这个问题是SO问题的副产品 c#代码似乎得到优化的无效方式,使对象值变为空,我试图帮助 Gary 与昨天晚上。他是一个发现有问题的人,我只是把问题减少到一个更简单的项目,并希望验证,然后再进一步与它,因此这里的问题。

This question is a by-product of the SO question c# code seems to get optimized in an invalid way such that an object value becomes null, which I attempted to help Gary with yesterday evening. He was the one that found out that there was a problem, I've just reduced the problem to a simpler project, and want verification before I go further with it, hence this question here.

如果其他人可以验证他们也遇到这个问题,我会在Microsoft Connect发布一个注释,当然,我希望Jon,Mads或Eric也会看看它:)

I'll post a note on Microsoft Connect if others can verify that they too get this problem, and of course I hope that either Jon, Mads or Eric will take a look at it as well :)

它包括:


  • 3个项目,其中2个是类库,是一个控制台程序(最后一个不需要重现的问题,但只是执行这显示了问题,而你需要使用反射器,看看编译的代码,如果你不添加它)

  • 不完整的参考和类型推断

  • 泛型

这里:代码存储库

我将在下面描述如何制作项目,如果你想要弄脏你的手。

I'll post a description below of how to make the projects if you rather want to get your hands dirty.

在方法调用中产生一个无效的转换,然后返回一个简单的通用列表,将它转换为某种奇怪的东西,然后返回它。原始代码结束了一个转换为布尔值,是的,一个布尔值。在返回结果之前,编译器将一个 List< SomeEntityObject> 的转换添加到布尔,并且方法签名表示它将返回 ; SomeEntityObject> 。这反过来在运行时导致奇怪的问题,从方法调用的结果被认为优化离开(原始问题),或与 BadImageFormatException 或崩溃 InvalidProgramException 或类似的例外之一。

The problem exhibits itself by producing an invalid cast in a method call, before returning a simple generic list, casting it to something strange before returning it. The original code ended up with a cast to a boolean, yes, a boolean. The compiler added a cast from a List<SomeEntityObject> to a boolean, before returning the result, and the method signature said that it would return a List<SomeEntityObject>. This in turn leads to odd problems at runtime, everything from the result of the method call being considered "optimized away" (the original question), or a crash with either BadImageFormatException or InvalidProgramException or one of the similar exceptions.

在我的工作重现这个, void [] ,现在我的代码的当前版本转换为 TypedReference 。在一种情况下,反射器崩溃,所以很可能的代码在这种情况下超出希望。

During my work to reproduce this, I've seen a cast to void[], and the current version of my code now casts to a TypedReference. In one case, Reflector crashes so most likely the code was beyond hope in that case. Your mileage might vary.

以下是重现它的方法:

注意: strong>很可能有更多的最小的形式,将重现的问题,但将所有的代码只是一个项目,使它消失。从类中删除泛型也使得问题消失。

Note: There is likely that there are more minimal forms that will reproduce the problem, but moving all the code to just one project made it go away. Removing the generics from the classes also makes the problem go away. The code below reproduces the problem each time for me, so I'm leaving it as is.

我为下面的代码中的转义的html字符道歉,这是Markdown对我的一个诡计,如果有人知道我该如何纠正它,请让我知道,或只是编辑


  1. 为.NET 4.0创建一个包含控制台应用程序的新Visual Studio 2010解决方案

  2. 添加两个新项目,类库和.NET 4.0假设它们命名为ClassLibrary1和ClassLibrary2)

  3. 调整所有项目以使用完整的.NET 4.0运行时,而不仅仅是客户端配置文件

  4. 添加a在控制台项目中引用ClassLibrary2

  5. 将ClassLibrary2中的引用添加到ClassLibrary 1

  6. 删除默认添加的两个Class1.cs文件到类库

  7. 在ClassLibrary1中,添加对System.Runtime.Caching的引用

  8. 向ClassLibrary1添加一个新文件, DummyCache.cs,并粘贴以下代码:
  1. Create a new Visual Studio 2010 solution containing a console application, for .NET 4.0
  2. Add two new projects, both class libraries, also .NET 4.0 (I'm going to assume they're named ClassLibrary1 and ClassLibrary2)
  3. Adjust all the projects to use the full .NET 4.0 runtime, not just the client profile
  4. Add a reference in the console project to ClassLibrary2
  5. Add a reference in ClassLibrary2 to ClassLibrary 1
  6. Remove the two Class1.cs files that was added by default to the class libraries
  7. In ClassLibrary1, add a reference to System.Runtime.Caching
  8. Add a new file to ClassLibrary1, call it DummyCache.cs, and paste in the following code:

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并粘贴以下代码:

  • Add a new file to ClassLibrary2, call it Dummy.cs and paste in the following code:

    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:

  • Paste in the following code in Program.cs in the console project:

    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();
            }
        }
    }
    


  • 确保没有编译器错误

  • Build, and ensure there are no compiler errors

    查看Dummy.GetDummies在Reflector中生成的代码。源代码如下所示:

    Look at the generated code of Dummy.GetDummies in Reflector. The source code looks like this:

    public List<Dummy> GetDummies()
    {
        var policy = Cache.GetDefaultCacheItemPolicy();
        return new List<Dummy>();
    }
    

    但是反射器说(对我来说,你,在一种情况下,反射器甚至崩溃):

    however reflector says (for me, it might differ in which cast it chose for you, and in one case Reflector even crashed):

    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;
    }
    


  • 几个奇怪的事情,上面的崩溃/无效代码搁浅:

    Now, here's a couple of odd things, the above crash/invalid code aside:


    • Library2,它有 Dummy。 GetDummies ,执行调用以从Library1获取类上的默认缓存策略。它使用类型推断 var policy = ... ,结果是一个 CacheItemPolicy 对象但是类型很重要)。

    • Library2, which has Dummy.GetDummies, performs a call to get the default cache policy on the class from Library1. It uses type inference var policy = ..., and the result is an CacheItemPolicy object (null in the code, but type is important).

    但是,ClassLibrary2没有引用System.Runtime.Caching,因此不应该编译。

    However, ClassLibrary2 does not have a reference to System.Runtime.Caching, so it should not compile.

    确实,如果你注释掉在Dummy中名为 TryCommentingMeOut 的方法,你会得到:

    And indeed, if you comment out the method in Dummy that is named TryCommentingMeOut, you get:


    类型System.Runtime.Caching.CacheItemPolicy在未引用的程序集中定义。您必须向程序集System.Runtime.Caching,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'添加引用。

    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'.

    为什么有这个方法存在使编译器快乐我不知道,我甚至不知道这是否链接到当前的问题或不。

    Why having this method present makes the compiler happy I don't know, and I don't even know if this is linked to the current problem or not. Perhaps it is a second bug.

    DummyCache 中有一个类似的方法,如果您还原方法在 Dummy 中,以便代码再次编译,然后注释掉在 DummyCache

    There is a similar method in DummyCache, if you restore the method in Dummy, so that the code again compiles, and then comment out the method in DummyCache that has the "Try commenting this out" comment above it, you get the same compiler error

    推荐答案

    OK,我下载了您的代码,并可以按照所述确认问题。

    OK, I downloaded your code and can confirm the problem as described.

    我没有做任何大量的修改,但是当我运行&反射器a发布版本似乎都OK(= null ref异常和干净反汇编)。

    反射器(6.10.11)在Debug版本中崩溃。

    I have not done any extensive tinkering with this, but when I run & reflector a Release build all seems OK (= null ref exception and clean disassembly).
    Reflector (6.10.11) crashed on the Debug builds.

    另一个实验:我想知道CacheItemPolicies的使用,所以我用我自己的MyCacheItemPolicy(在第三个classlib)替换它,同样的BadImageFormat异常弹出。

    One more experiment: I wondered about the use of CacheItemPolicies so I replaced it with my own MyCacheItemPolicy (in a 3rd classlib) and the same BadImageFormat exception pops up.

    异常提示:{错误的二进制签名(来自HRESULT的异常:0x80131192)}

    The exception mentions : {"Bad binary signature. (Exception from HRESULT: 0x80131192)"}

    这篇关于可能的C#4.0编译错误,可以别人验证吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆