🌊

.NET と .NET Framework でエラーメッセージが違って悩んだ記録

2023/07/19に公開

個人的な学び

  • 動作環境を調査対象環境とあわせて調査すること

起きてたこと

dynamic someString = "fetched data expected to be iterable object";
foreach(var k in someString["body"]) // <-- here
{
    Console.WriteLine(k);
}

コアの問題として dynamic 型の変数が予期せず string になっていたことがあり、過去事象からこの問題を疑った。

ただ、このとき上記の here のところで

The best overloaded method match for 'string.this[int]' has some invalid arguments

というエラーが起きており、このメッセージが疑っていた問題に対して、すぐに噛み合って納得できなかった。

考えたこと

variable["key"]variablestring であることを疑ってはいたものの(確信がなかったこともあり)どうにもエラーとあわないと一旦スルーしてしまった。
しかし string.this[int]string 型のインデクサを指していることは当然として、実際のコードで "string"[0] のようなコードはなく(そもそも char を取る場面がなかった)、しばらくコードを彷徨うことになった。

他の可能性が考えにくかったので、あらためて上記のコードブロックを疑い、ローカルでは次のように確認したところエラーが違っていた。

var someString = "fetched data expected to be iterable object";
foreach(var k in someString["body"])
{
    Console.WriteLine(k);
}
Argument 1: cannot convert from 'string' to 'int'

そこで、フレームワーク違いを疑って、型とフレームワークの組み合わせで確認したところエラーはそれぞれ次のようになることがわかった。

エラーメッセージ的には、cannot convert from 'string' to 'int' と言ってくれたほうが個人的にはわかりやすいと感じた。
(謎が解けて振り返ると、まあ分からないではないメッセージではあるが、過去の事象から疑いが見えてないともっと悩んだだろうなと思う)

ただ dynamic では CallSite`` を経由して動的にメソッドを選択する都合上 some invalid` としか言えないことは想像に難くない。

まとめ

調査がうまく進まなかった原因は 2 点

  1. 実環境では、変数は関数の呼び出しの結果を代入していたので vardynamic に推論されていた(上記検証コードでは varstring に推論される)
  2. ローカルでは .NET 7 を利用していた(問題が発生していた環境は .NET Framework 4.7 系)

今回は .NET Fiddleを利用することで手軽に差異を確認できたので、環境をあわせての確認に注意したい。

Discussion