質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

395閲覧

ジェネリッククラスに要素を追加すると、最後のファイル名のみ反映されてしまう

sheephuman

総合スコア112

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/07/14 09:37

編集2017/07/14 11:31

###発生している問題・エラーメッセージ

ディレクトリ下にあるファイル名(rtf)を列挙 (button1)
┗「Data」フォルダ以下に Form1.rtf ~ Form4.rtf までを用意

上記で取得したファイル名をXMLとして保存 (button2)

という処理の流れで、最後に取得したファイル名のみ反映され、出力結果が <FileName>Form4.rtf</FileName> のみとなってしまいます。

上書きされてしまうようですが、正常に反映させる方法が分かりません。

参考にした記事
C#で付箋紙を作る(第三回目) XMLファイルからパラメーターを読み込んで反映する

関連のある質問
ListにAddする再、何故か全てのデータがAddしたデータに上書きされてしまいます。

###該当のソースコード

C#

1 2 private void Form1_Load(object sender, EventArgs e) 3 { 4 setCurrent = Directory.GetCurrentDirectory(); 5 6 } 7 8 9 10 /// <summary> 11 /// //カレントディレクトリ下にある”Data”フォルダ内のファイル名を列挙 12 /// </summary> 13 string setCurrent; 14 static StickyList SL; 15 static StickyData SD; 16 private void button1_Click(object sender, EventArgs e) 17 { 18 SD = new StickyData(); 19 SL = new StickyList(); 20 SL.DataList = new List<StickyData>(); 21 ///インスタンス化 22 23 string[] files = Directory.GetFiles(setCurrent +"\\Data\\", "*.rtf", SearchOption.TopDirectoryOnly); 24 //”Data”フォルダ下のフルパスを取得 25 26 foreach (string filename in files) 27 { 28 string s = Path.GetFileName(filename); 29 //フルパスをファイル名に変換 30 31 32 SD.FileName = s; 33 34 SL.DataList.Add(SD); //この時点で、SD内にはForm4.rtfしか存在しない 35 //上書きされる 36 37 listBox1.Items.Add(SD.FileName); //結果のプレビュー 38 39 40 41 } 42 43 } 44 45 private void button2_Click(object sender, EventArgs e) 46 { 47 48 49 var serializer = new XmlSerializer(typeof(StickyList)); 50 //XMLシリアライズクラスを初期化(インスタンス化) 51 52 53 var sw = new StreamWriter(@"Sticky.xml", false, new UTF8Encoding(false)); 54 serializer.Serialize(sw, SL); 55 //シリアライズして書き込む 56 57 sw.Close(); 58 } 59 60 #region ジェネリッククラス 61 62 /// <summary> 63 /// XMLとして保存するクラス 64 /// </summary> 65 [XmlRoot("Sticky")] 66 public class StickyData 67 { 68 [XmlElement("FileName")] 69 public string FileName { get; set; } 70 } 71 72 /// <summary> 73 /// StickyDataをジェネリックリスト化するクラス 74 /// </summary> 75 [XmlRoot("Stickys")] 76 public class StickyList 77 { 78 [XmlElement("Sticky")] 79 public List<StickyData> DataList { get; set; } 80 } 81 82 #endregion 83

###出力結果

<?xml version="1.0" encoding="utf-8"?> <Stickys xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Sticky> <FileName>Form4.rtf</FileName> </Sticky> <Sticky> <FileName>Form4.rtf</FileName> </Sticky> <Sticky> <FileName>Form4.rtf</FileName> </Sticky> <Sticky> <FileName>Form4.rtf</FileName> </Sticky> </Stickys>

###補足情報(言語/FW/ツール等のバージョンなど)
listbox1内の出力は正常でした。

イメージ説明

変数
SLがbutton1 クリック時にFileName”Form4”の重複が見られました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

たぶん、「ListにAddする再、何故か全てのデータがAddしたデータに上書きされてしまいます。」と同じ原因です。

ListへのaddはSDのデータではなく、SDへのポインタがaddされるだけです。
SD = new StickyData();をforeachループの中に入れれば解決する筈です。

List<T>.Add メソッド (T)のサンプルが参考になるかも。

投稿2017/07/14 11:04

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sheephuman

2017/07/14 11:09

あ、なるほど・・・ foreachループ内でその都度newすればよかったんですね! 関連の質問みつけたのはいいものの、外側でnewしても単に初期化されちゃうだけなんで、どうしたものかと思ってたんですが・・・・  目から鱗でした(;´・ᴥ・)
guest

0

XmlRoot属性が複数になっているからじゃないですか?

投稿2017/07/14 09:50

hihijiji

総合スコア4150

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sheephuman

2017/07/14 09:54

よくわかりません。 [XmlRoot("Stickys")] を削除するなどでしょうか?
hihijiji

2017/07/14 09:57

そちらはルートっぽいので、削除するなら[XmlRoot("Sticky")]のほうです。
sheephuman

2017/07/14 10:03

すいません。削除しても出力結果が変わりません。  試しに要素を全部削除して実行したら、   <DataList> <StickyData> <FileName>Form4.rtf</FileName> </StickyData> ×4ループ  となりました。  この場合、ルート要素の変更は処理に影響を与えないのでは。
hihijiji

2017/07/14 10:09

そこじゃなかったですm(__)m static StickyData SD; これは使わずに都度 new StickyData() として新しいインスタンスを作ってListに追加してください。
sheephuman

2017/07/14 10:18

うーん・・・ほかにジェネリック配列を定義して移したりもしたんですが、リストの追加でつまずいてしまいます。  もう少し勉強してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問