2017-10-13 1 views
3

私はF#で書かれたWebApiプロジェクトに取り組んでいます。ここでは、スニペット:F#Guid.Parse TypeInitializationException

module MyModule 

open System 

let MyGuid = Guid.Parse "934F0B12-D00A-491D-862D-EE745EF3C560" 

let myFunction list = 
    list.Get(MyGuid) // --> here MyGuid has the TypeInitializationException before list.Get is called 

私はMyGuidが実際にエラーコード以下の変更

を持っていることがわかりますデバッグすることで、それが動作:

module MyModule 

open System 

let MyGuid() = Guid.Parse "934F0B12-D00A-491D-862D-EE745EF3C560" 

let myFunction list = 
    list.Get(MyGuid()) 

私は実際には最初のMyGuidを知っていますexampleは変数であり、2つ目は関数の定義ですが、なぜ最初に例外が発生しますか?私のコードMyGuidは何度か使用されています。最初の例では、私はMyGuidが呼び出されるたびに2番目に新しいインスタンスが1つしかないでしょう...

+0

'list'のタイプと' list.Get'とは何ですか? – scrwtp

+1

'TypeInitializationException'のテキストは何ですか?その 'InnerException'? –

+0

'list'と' list.Get'が何であるかは関係ありません。この時点で、 'MyGuid'はすでに' faulty'です。 Innerexceptionsを見ることができません。「MyGuid」だけが 'System.TypeInitializationException'型の例外をスローしました。 – Emaborsa

答えて

2

私はこれが問題であることを100%確信していませんが、私は見ました単位テストランナーを時々使用するときの同様の挙動。トップレベルのMyGuid変数が正しく初期化されておらず、デフォルトのゼロ値を持ち(結果としてルックアップが失敗するため)、エラーが発生すると私は推測します。

F#でグローバル変数を初期化する方法は難しいです。実行可能コードとしてコードをコンパイルすると、これはMainメソッドから発生します。しかし、コードをライブラリとしてコンパイルすると、コンパイラはライブラリの型の静的コンストラクタに初期化チェックを挿入します(何かにアクセスする前にすべてが初期化されていることを確認します)。

実行可能ファイルとしてコードをコンパイルしてからライブラリとしてロードすると、これが壊れる可能性があります。エントリポイントは呼び出されず、変数は初期化されません。私はWebApiがどのようにライブラリをロードするのかよく分かりませんが、これは問題になる可能性があります。特に、F#コードを実行可能ファイルとしてコンパイルする場合は特にそうです。

グローバル変数を関数に変換する回避策は、関数がメソッドとしてコンパイルされ、初期化されていない値を参照しないようにするため、これを修正します。残念ながら、私はこれのためのより良い回避策はないと思います。

+0

前述のように、問題は 'list.Get'を呼び出すことによる検索ではありません。この行にブレークポイントを設定すると、Guidインスタンスの代わりにこのTypeInitializationExceptionが内部にあります。私はWebプロジェクト 'WebApi'に取り組んでいます。現時点ではバグだと思います。 – Emaborsa

+0

@Emaborsaこれは答えとしてマークされている - これの背後にある問題は何ですか?私の推測は近いのですか、それとも別のものでしたか? –

+0

私は問題が何であるか分かりません。静的変数を関数に変換しました。私は、同じGUIDの複数のインスタンスを避けるために、私は一種のシングルトンモジュール/クラスを作成するより大きいプロジェクトの場合は、 – Emaborsa

関連する問題