2017-06-13 6 views
1

私はそうのように使用してIEnumerable<T>を返すメソッドyield returnを書いている:なぜVisual Studioは私の "yield return"メソッドが動的オブジェクトを返すと思いますか?

public IEnumerable<Row> ConvertExcelToRows(IExcelDataReader reader) 
{ 
    while (reader.Read()) 
    { 
     var row = new Row(); 
     // do some work. No dynamic objects here whatsoever 
     yield return row; 
    } 
} 

私は私の方法を消費し、LINQの拡張メソッドでそれに従って、Visual Studioは、タイプdynamicであることが、戻り値を示しています

ここで

enter image description here

症状に至るまで、関連するコードです:

dynamic data = JsonConvert.DeserializeObject(jsonContent); 
using (var stream = await DownloadFile(data.docUrl.ToString())) 
using (var excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream)) 
{ 
    var rows = ConvertExcelToRows(excelReader).ToList<Row>(); 
} 

それはList<Row>なければならない時には、上記撮影画面内rowsのタイプはdynamicあります。

なぜこれが起こって、どのように私はそれを修正することができますか?

(は私が書いただけのクラスであることに注意してくださいそれはすべてのプリミティブな特性、ダイナミック何も。)

をKEY UPDATE:上のスクリーンショットを改善する過程で、私はの宣言を変更しましたexcelReaderからvarからIExcelDataReaderまでである。 これは私の問題を解決しました。

私がvarに戻ったとき、推測されたexcelReaderのタイプが確かに伝染性のあるdynamicであることがわかりました。

はまだ私の方法への動的な入力引数は、出力のタイプを「感染」する理由の説明が大好きです。

+4

'dynamic'は[セリウム、地獄伝染原理のいくつかの種類(https://blogs.msdn.microsoft.com/ericlippert/2012/11/08/dynamic-contagion-part-two/)によって動作します。それに踏み込んだりブラシをかけたりするものは何でもあります(http://static.tvtropes.org/pmwiki/pub/images/invasion-of-the-body-snatchers-78_5124.jpg)。Late Binding Zoneへのポータルを開くと、コンパイラーは気まぐれで妄想的になり始めます。 –

+2

コード内に_everything_を定義する必要があります。 'rows'変数の型、' excelReader'変数の型、戻り値に関連するあなたの "do some work"コードが何をするかを示してください。私たちが作ることができる仮定に基づいて、うまくいくはずですが、あなたは私たちにあなたを信じる理由を与えていません。 –

+1

上流のものが「動的」です。あなたは何を見つける必要があります。 –

答えて

5

dynamiccontagion principleで動作します。式に入るものがdynamicなら、コンパイラはコンパイル時に何が出てくるのか保証することができないので、出てくるものはdynamicと考えられます。実行時に型が任意に変更される可能性がある場合、コンパイラが実行できる静的解析には限界があります。

したがって、式から出てくるものがdynamicであり、結果が明示的にdynamic変数に割り当てられていない場合は、dynamicが入っている必要があるためです。このメソッドに明示的に何かを渡さないとdynamic、あなたがそれを与えたものは他の場所に "感染している"必要があります。

何か上流、方法、あなたは上のメソッドを呼び出したオブジェクト、または式の用語へのパラメータは、dynamicあります。あなたは何を見つける必要があります。

明らかな候補はexcelReaderです:どこから来たのですか。オブジェクトはどこから来たのですか?メソッドを与えたパラメータ(もしあれば)は何でしたか、どこで取得しましたか?

患者ゼロはどこかにあります。

+0

Spot on。患者ゼロは 'data.docUrl.ToString()'でした。 '(string)data.docUrl'に変更すると修正されました。 'dynamic'の' ToString() 'が' string'ではなく 'dynamic'であると推測されていることに驚きました。 – urig

+1

'ToString()'は 'dynamic'の上に絶対に何かがあります。オブジェクトが「動的」になると、通常の静的解析は適用されません。 –

+1

@urig OMG JSON。私はそれに気をつけておくべきです。とても信じられないほど便利です。とても魅力的です。 –

関連する問題