2016-10-26 7 views
2

。ここではネット4.5.2 ...注文(条件、interpolatedStringMessage)

私は中!ContainsKey()チェックしていました値を含む補間文字列でDebug.Assert()は、見つかった場合、その

var dict = new Dictionary<string, string>(); 
string invalidKey = "invalidKey"; 

try 
{ 
    Debug.Assert((!dict.ContainsKey(invalidKey)), $"{nameof(dict)} contains the key {dict[invalidKey]}!"); 
} 
catch (KeyNotFoundException) 
{ 
    Console.WriteLine("AssertionString was interpolated before the check was performed!"); 
} 

(唯一の私の最初のバージョンでtry-catchブロックなし)

ように私はそこcatchに実行されないと予想ただろうeの場合も同様である。 g。 .NETFiddle内のコードをチェックする(https://dotnetfiddle.net/RyQooWを参照)、ただし、Visual Studioで、ネット4.5.2の下でコードを実行している、私は次を得る:

interpolated string evaluated before assertion condition

をそれは間違いなく、文字列の補間(とではありません問題はContainsKey)、メッセージから補間を取り除くと、例外がスローされないためです。

評価の順序は保証されていませんか?アサーションが真実なら、文字列は補間されないと思った。

または.NETランタイムのこのバージョンでは、この単なるエラー(多分、最適化、それらが静的か何かにするために、早期アサーション文字列を補間する?)

任意の入力をありがとう、と歓声です!

+0

お使いの.NETバージョンは? v4.6.1では例外がありません。 – dymanoid

+0

@dymanoid 4.6.1同様、Windows 8.1システムでVS 2015 Update 3 –

答えて

2

さて、あまりにも、この上でつまずく皆のためそれほど:

、それは明らかに、ないバグですが、実際には、単にDebug.Assert等、通常の方法(ではないいくつかの特別な組み込みのヘルパー、さMicrosoft's reference sourceも参照してください)、の文字列引数には、が入力される前に補間されるが含まれています(対象のオブジェクトが呼び出しスコープ外で使用できない可能性があるため)。
両方の条件及びメッセージは、メソッドの引数であり、条件の評価は、(評価の結果ようないメソッド呼び出し)内部メソッドに発生するので、上記KeyNotFoundExceptionは勿論ですメソッドが入力され条件がチェックされる前にスローされます。

Debug.Assertを特殊なものにするのは、[System.Diagnostics.Conditional("DEBUG")]属性を持つため、非デバッグビルドでは削除されます。

これは実際には完全に理解でき、正しく動作しています(ドットネットバージョン)。しかし、これはちょっとした落とし穴です。

+1

はい、まさにそのようなものです。これは通常のメソッドなので、すべてのパラメータの値は呼び出し前に計算されます。したがって、パラメータ#2の式はすぐに例外を発生させます。他の振る舞いを強いられる唯一の方法は、 '(bool、Func )'のような 'ジェネレータ'を必要とする場合に呼び出される 'Assert'メソッドを書くことです。 'Assert(!dict。あなたのアサーションメッセージは本当に奇妙に見えますが、(x)、()=> $ "dict {dict [x]}");私は個人的に 'Assert(!dict.contains(x)、$" oopsはキー{x}を含んでいました ")と書いています。 – quetzalcoatl

+0

@quetzalcoatl Uhhh、ええ、それを一般化しようとすると、あなたはそれを修正する必要があると思いますか?それで、それを編集することでもう一度質問に挑戦しますか?) –

+0

あなたは質問をしてくれました。それを残す。私はちょうどあなたが例外の実際の原因であったこの愚かなタイプミスを見落としたかもしれないと思った:私はそれをそのまま残してもいいと思う、歓声。 – quetzalcoatl