3

ジェネリック メソッドを持つ非ジェネリック クラスがあります。このメソッドのジェネリック型は出力型を定義し、使用法から推測できないため、明示的にジェネリック型を提供する必要があります。この型は、ジェネリック呼び出し元のメソッド型パラメーターから渡されることもありますが、あるインスタンスでは、自分で明示的に指定する必要があります。

問題は、明示的に提供されたジェネリック型メソッド呼び出しを呼び出すと、実行されず、まったく無関係な型が返されるように見えることです。この呼び出しにデバッグできず、無効な結果が得られます。しかし、特に奇妙なことに、実行が中断されることはありません。ジェネリック型が呼び出し元のジェネリック メソッド型から渡される他の場所から同じメソッドが呼び出されると、すべてが定義どおりに機能するように見えます。

私は何が起こっているのか完全に失われています。

インターフェイスでの私のメソッド定義(およびクラスで後で実装されます):

TRecord Update<TRecord>(int recordId, int? categoryId, string categoryName, string title)
    where TRecord : Record;

Recordのクラスは抽象的ではなく、継承する型は 1 つだけです。

public class Record : ProtectedEntity
{
    ...
}

public class RelatedRecord<T> : Record
{
    public IList<T> Related { get; private set; }
    ...
}

私はこれを行うメソッドを呼び出しています:

var record = myRepo.Update<Record>(...);

実行がこの行にF11到達すると、デバッグするためにヒットしますが、実行は次の文にジャンプするだけです。record変数をチェックすると、タイプRecordではなくSystem.String、パラメータの値を持っていますcategoryName。これは、何かが実行されることを意味しますが、それは間違いなく私のジェネリック メソッドの本体ではありません。

奇妙なことに、他の場所では同じ呼び出しが期待どおりに機能します。

これはどのように説明でき、何が間違っているのでしょうか?

4

2 に答える 2

2

コメントを含むあなたの言っていることから:

実行時にメンバーにアクセスしようとすると、もちろん、存在しないメンバーに関する例外がスローされます。

コンパイラのバグか JIT のバグのようです。つまり、診断するには、使用しているコンパイラ (正確なバージョン) および/または使用している JIT に関するより多くの知識が必要です。コンパイラのバグの場合、慣れている場合は、生成された IL を表示するだけで十分な場合があります。

最新の VS プレビューには、まったく新しい JIT (RyuJIT) が含まれており、デフォルトでシステム全体で有効になっていることに注意してください。したがって、VS プレビューをインストールしていれば、それが私の推測です。その場合は、簡単に無効にして確認できます。


ここでの他のオプションは、エイリアスが であるエイリアス、またはエイリアスであるエイリアスのようなものであることに注意してください(さらにusing、いくつかの暗黙的な変換演算子など)。これらは起こりそうにありませんが、私はそれが起こるのを見てきました;pRecordSystem.StringvarSystem.String

編集:上記はあなたのコメントによって除外されています:

typeof(Record).FullName を実行すると、名前空間を含む完全な型名が正しく返されます。

そのため、コンパイラのバグまたは JIT のバグが残っています。


これが RyuJIT のバグである場合は、これを無効にするオプションを次に示します (最も簡単な方法であるため、最初に構成を使用することをお勧めします)。

  1. 環境変数として: セット COMPLUS_useLegacyJit=1

  2. レジストリで: HKLM または HKCU、Software\Microsoft.NETFramework を設定します。キー名: useLegacyJit. タイプ: REG_DWORD。値: 1

  3. app.exe.config ファイル内:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <runtime>
        <useLegacyJit enabled="1" />
      </runtime>
    </configuration>
    

(これらは、私が以前行った MS との別の議論から来ています)

于 2014-12-30T12:22:56.390 に答える