4

今日、解決できた非常に奇妙な問題が発生しましたが、なぜこれが起こっているのかまだわかりません。これはシナリオです:

編集

シナリオをより単純なものに変更しました。コードを実行するプログラムと、2 つのインポーター、ジェネリック型を持つ基本クラス、および基本メソッドを呼び出して反復する別のクラス (ImplementingImporter) があります。これは完全なコードです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IEnumeratorLoadProblem {
    class Program {
        static void Main(string[] args) {

            var importer = new ImplementingImporter();
            try {
                var data = importer.GetData().ToArray();
            } catch (BadImageFormatException ex) {                
                Console.WriteLine("Why does this fail? " + ex.ToString());
            }

            Console.WriteLine("Press enter to quit");
            Console.ReadLine();
        }
    }

    class BaseClassImporter<T> {

        public virtual IEnumerable<T> GetData() {
            yield break;
        }
    }

    class ImplementingImporter : BaseClassImporter<int> {
        public override IEnumerable<int> GetData() {
            // iterating seems to cause the problem
            foreach(var dataByBaseImpl in base.GetData()) {
                yield return dataByBaseImpl;
            }
        }
    }
}

次のエラーが表示されます。

System.BadImageFormatException: 不正な形式のプログラムを読み込もうとしました。(HRESULT からの例外: 0x8007000B)

使用されているインポーターからコードを変更すると、次のように機能します。

class ImplementingImporter : BaseClassImporter<int> {
    protected override IEnumerable<int> GetData() {
        return base.GetData();
    }
}

残念ながら、ILSpy と Reflector.NET (バージョン 6) の両方が内部エラーを表示したため、生成された IL コードを確認できませんでした (これは anArgumentOutOfRangeException だったと思います)。ildasm を使うのが怖かったので、IL Code を直接見ようとはしませんでした。

生成された IL コードと関係があると思いますが、問題の原因となっているシナリオは考えられません。

ここで何が起こっているのですか?シナリオが十分に明確でない場合は、コメントを残してください。より明確にするよう努めます。

編集:

使用した .NET バージョン: 4.0。アプリケーションは、VS 2010 SP1 を使用する ConsoleApplication です。ビルド プラットフォームのターゲットは AnyCPU ですが、x86 を使用している場合にも問題が発生します。私のマシンには 64 ビット システム (Windows 7) があります。この例外は、.NET 4.0 クライアント プロファイルを使用している場合にも発生します。

この例は単一のプロジェクトであり、外部/管理されていないライブラリは使用されていないため、推奨される問題 (64 ビットの実行時に 32 ビット アセンブリを参照するなど) のみが発生することはありません。

4

2 に答える 2

4

yield returnこれは、次のステートメントのバグのようです。

https://connect.microsoft.com/VisualStudio/feedback/details/677532/an-attempt-was-made-to-load-a-program-with-an-incorrect-format-exception-from-hresult-0x8007000b#詳細

彼らは、VS2012(または「VS 2010以降のバージョン」)で修正されたと述べています。

VS2010 SP1 を使用して .NET Framework 4 を対象とするコンソール アプリケーションを実行していますが、あなたと同じエラーが発生することを確認できます。これを試すための VS2012 インストールがありません。

同様の質問がここで尋ねられました:

イテレータ ブロックと継承

別の疑わしい同様の例 (今回は非同期ですが、MoveNext再びトリガーされます):

C#5 AsyncCtp BadImageFormatException

その他のリソース:

于 2012-08-14T14:09:45.917 に答える
0

すべてのプロジェクトが同じコンパイル オプション (AnyCPU、x86、または x64) を使用していることを確認してください。

外部 dll を使用する場合は、互換性があることを確認してください (x86 マシンでは 32 ビット、x64 マシンでは 64 ビット)。

x64 マシンで 32 ビット dll を使用する場合は、メインの .exe を「任意の CPU」ではなく「x86」としてコンパイルするように設定する必要があります。これにより、アプリ全体が 32 ビット プロセスとして実行されます。 64 ビット PC で。(これを行わないと、exe は x64 マシン上で 64 ビット アプリとして JIT コンパイルされ、32 ビット dll を呼び出そうとすると、取得している例外がスローされます)

于 2012-08-14T13:26:48.103 に答える