C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

■86556 / 1階層)  CSVHelperでマッピングがうまくいかない
□投稿者/ 魔界の仮面弁士 (1564回)-(2018/02/14(Wed) 11:11:35)
No86553 (MGS さん) に返信
> MyClass内foreachでNullReferenceExceptionが発生します。

foreach での列挙が始まる前に、using によって Dispose されているためです。
GetRecords<T> メソッドは、遅延実行されるメソッドですので、
列挙が完了するまでは using してはいけません。

ファイルが小さいものである場合には、後述するように
return 時に .ToArray() メソッドを補って即時実行するのが良いでしょう。

ファイルが大きく、全件一括取り出すのが困難な場合には、プログラムを組み替えて
foreach し終わってから Dispose されるように変更してみてください。


> Public DataClass : IData
これだとコンパイルが通らないような。
「public class DataClass : IData」でしょうか。

IData インターフェイス、あるいは IData クラスは独自定義のものですか?
今回の実装だと、ここの定義も重要になってきます。


> public class CsvReader
この名前は、CsvHelper 名前空間の CsvReader クラス、すなわち
>  using (var csv = new CsvHelper.CsvReader(new StreamReader(filename)))
と被りますよね。

名前空間で区別できるとはいえ、初見では見分けが付きませんでした。
混乱を避けるため、別のクラス名にしておいた方が良いかと思います。掲示板でのやり取りにおいては特に。


> public IEnumerable<IData> Read(IData data, string filename)
data 引数のインスタンスが、型指定のためにしか使われていないのが気にかかりました。

複数の CSV に対応させるなら、
 public IEnumerable<T> Read<T>(string filename) where T : IData
あるいは
 public IEnumerable<IData> Read(Type type, string filename)
で十分な気がするのですが、実際のコードはもっと複雑だということでしょうか。


> return csv.GetRecords<IData>();
列挙したいレコード情報は DataClass 型なのですから、
型パラメーターを IData 型にしてはマズイです。

戻り値を IEnumerable<DataClass> にして、
 return csv.GetRecords<DataClass>().ToArray();
にしてみてください。

戻り値を IEnumerable<IData> のままにしておきたい場合には、
 return csv.GetRecords<DataClass>().OfType<IData>().ToArray();
という感じです。


> public MyClassMap()
これは…メソッドではなさそうですね。もしかして
 public sealed class MyClassMap : CsvHelper.Configuration.ClassMap<DataClass>
あたりのコンストラクタでしょうか。



> Map(m => m.SignedDate).Index(1).TypeConverter(new DateTimeConverter());
ここでいうと DateTimeConverter というのは、独自定義の
「public sealed class DateTimeConverter : CsvHelper.TypeConversion.ITypeConverter」
でしょうか。それとも、
CsvHelper.TypeConversion.DateTimeConverter
をそのまま使っているのでしょうか。

恐らくは後者だと思いますが、CsvReader は独自定義で用意されていたので、念のため確認。


> CsvReader csv = new CsvReader();
> IData data= new DataClass();
> IEnumerable<IData> list = csv.Read(data, this.txtCSV.Text);

ここの CsvReader は CsvHelper.CsvReader ではなく、
独自定義の「public class CsvReader」の方ですね。



> IEnumerable<IData> list = csv.Read(data, this.txtCSV.Text);
> foreach (DataClass d in list)

IEnumerable<IData> を「foreach (DataClass d in list)」に渡すのは
違和感があるので、私なら、ここの列挙は
 foreach (var d in list.OfType<DataClass>())
のように書くかと思います。

IEnumerable<IData> で受けて、「foreach (IData d in list)」とか
IEnumerable<DataClass> で受けて、「foreach (DataClass d in list)」とか
IEnumerable<DataClass> で受けて、「foreach (IData d in list)」とするのなら
OfType は使わないですけれども。
編集キー/

前の記事(元になった記事) 次の記事(この記事の返信)
←CSVHelperでマッピングがうまくいかない /MGS →Re[2]: CSVHelperでマッピングがうまくいかない /MGS
 
上記関連ツリー

CSVHelperでマッピングがうまくいかない / MGS (18/02/14(Wed) 01:45) #86553
Re[1]: CSVHelperでマッピングがうまくいかない / Hongliang (18/02/14(Wed) 09:25) #86554
│├ Re[2]: CSVHelperでマッピングがうまくいかない / にゃるら (18/02/14(Wed) 10:38) #86555
││└ Re[3]: CSVHelperでマッピングがうまくいかない / MGS (18/02/14(Wed) 22:00) #86560 解決済み
│└ Re[2]: CSVHelperでマッピングがうまくいかない / MGS (18/02/14(Wed) 21:42) #86559 解決済み
CSVHelperでマッピングがうまくいかない / 魔界の仮面弁士 (18/02/14(Wed) 11:11) #86556 ←Now
  └ Re[2]: CSVHelperでマッピングがうまくいかない / MGS (18/02/14(Wed) 21:39) #86558 解決済み

上記ツリーを一括表示 / 上記ツリーをトピック表示
 
上記の記事へ返信