今回はGenericのListクラスを継承しAddメソッドを弄ることで、ダブルクォーテーションを付加しながらCSVを出力するプログラムを作った。
Collections.Generic.List<T>クラスは拡張性を犠牲にしてパフォーマンスを優先している。
そのため、継承して使うのは推奨されていないっぽい。
System.Collections.Generic.Listt<T>
は、継承ではなくパフォーマンスを目的としたジェネリック コレクションです。System.Collections.Generic.Listt<T>
には、継承クラスの動作を変更しやすくする仮想メンバーは含まれていません。引用元:CA1002: ジェネリック リストを公開しません – MSDN
でも、コンマ何秒の性能を重視するようなプログラムじゃないし、ちょっとくらいいいよね?
CSharperの先輩たちに見せたら怒られるかな?
Listクラスを継承してダブルクォーテーションで括る
まずはバッチ本体。ありきたりなループ処理。
static void Main(string[] args)
{
StreamWriter sw = new StreamWriter("C:\test.csv", false, Encoding.UTF-8)
foreach (なんかのループ)
{
CsvList<string> csvList = new CsvList<string>();
// 勝手にダブルクォーテーションでくくってくれる
csvList.Add("文字列");
csvList.Add("文字列");
csvList.Add("文字列");
// 書き込み
sw.WriteLine(String.Join(",", csvList.ToArray()));
}
sw.Dispose();
}
次に、Listクラスを継承したCsvListクラス
public class void CsvList<T> : System.Collections.Generic.List<string>
{
// Listt<T>のAddを隠蔽し再定義(orverrideできな
ため)
public new void Add(string item)
{
// ダブルクォーテーションで文字列を囲む
base.Add("\"" + item + "\"");
}
}
基礎:DBの値を取得して、CSVを出力する
なぜListクラスなんかを継承したのか。
単純にDBの値を取得して、そのままCSVを書き出すなら以下のプログラムでも良い。
// DB接続してデータを取得する処理(省略)
StreamWriter sw = new StreamWriter("C:\test.csv", false, Encoding.UTF-8);
List<String> csvLine = new List<String>();
// dtはDataTable
foreach (DataRow row in dt.Rows)
{
csvLine = new List();
for (int i; i < row.count; i++)
{
csvLine.Add("\"" + row[i].ToString() + "\""));
}
sw.WriteLine(String.Join(",", csvLine.ToArray());
}
sw.Dispose();
ただ、今回はそのままCSVに書き出すのではなく、編集や順番を変えて出力しなければいけなかったため、
csvLine.Add("\"" + row[i].ToString() + "\""));
の部分が、csvLine.Add("\"" + row["aaa"].ToString() + "\""));
csvLine.Add("\"" + row["bbb"].ToString() + "\""));
csvLine.Add("\"" + row["ccc"].ToString() + "\""));
csvLine.Add("\"" + row["ddd"].ToString() + "\""));
というように300行くらい続いていた。中には、単純に設定するだけでなくいろんな編集処理が混ざっており、美しくないと感じた。
おまけ
上記プログラムでは文字列結合に「+」を使用しているが、String.Concatの方が早いらしい。
ループ内でいっぱい結合するならStringBuilderの方が良い。
後日談だが、要件では「CSVファイルを出力して欲しい」って聞いてたのに、完成間近に無慈悲な仕様変更が発生。
客:やっぱ固定長ファイルでよろ~♪
CSVを固定長に変えるくらい簡単っしょ?
は?(ブチツ
これもいい機会なので、後日「C#で固定長ファイルを出力する」というエントリを書こうと思う。
転んでもタダで起きてたまるか!!
以上
0 件のコメント :
コメントを投稿