teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

コンパイル可能なソースを追記

2021/09/27 09:33

投稿

aki107205
aki107205

スコア1

title CHANGED
File without changes
body CHANGED
@@ -37,7 +37,97 @@
37
37
  }
38
38
  }
39
39
  ```
40
+ ### 動かせるソースコード例(追記)
40
41
 
42
+ ```C#
43
+ using System;
44
+ using System.Collections.Generic;
45
+ using System.IO;
46
+ using System.Linq;
47
+ using System.Text;
48
+ using System.Threading.Tasks;
49
+ using System.Xml.Serialization;
50
+
51
+ namespace TestApp
52
+ {
53
+ class Program
54
+ {
55
+ static void Main(string[] args)
56
+ {
57
+ //新規データ作成(デスクトップ)
58
+ string xmlFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "myData.xml");
59
+ var generator = new MyDataGenerator();
60
+ generator.GenerateAndSave(xmlFile);
61
+
62
+ //ファイルからロード
63
+ MyData myData = MyDataLoader.Load(xmlFile);
64
+
65
+ //利用(編集しない)
66
+ var user = new MyDataUser();
67
+ user.UseData(myData);
68
+
69
+ Console.ReadLine();
70
+ }
71
+ }
72
+
73
+ [XmlRoot("myData")]
74
+ public class MyData
75
+ {
76
+ public MyData() { }
77
+
78
+ [XmlElement("data1")]
79
+ public string Data1 { get; set; }
80
+
81
+ [XmlElement("data2")]
82
+ public string Data2 { get; set; }
83
+ }
84
+
85
+
86
+ class MyDataGenerator
87
+ {
88
+ public void GenerateAndSave(string path)
89
+ {
90
+ var myData = new MyData();
91
+ myData.Data1 = "abcde"; //実際はユーザー入力などを受け取って設定する
92
+ myData.Data2 = "fghij";
93
+
94
+ var xmlSerializer1 = new XmlSerializer(typeof(MyData));
95
+ using (var streamWriter = new StreamWriter(path, false, Encoding.UTF8))
96
+ {
97
+ xmlSerializer1.Serialize(streamWriter, myData);
98
+ streamWriter.Flush();
99
+ }
100
+ }
101
+ }
102
+
103
+ static class MyDataLoader
104
+ {
105
+ public static MyData Load(string path)
106
+ {
107
+ var xmlSerializer = new XmlSerializer(typeof(MyData));
108
+ MyData myData;
109
+ using (var streamReader = new StreamReader(path, Encoding.UTF8))
110
+ using (var xmlReader = System.Xml.XmlReader.Create(streamReader))
111
+ {
112
+ myData = (MyData)xmlSerializer.Deserialize(xmlReader);
113
+ }
114
+
115
+ return myData;
116
+ }
117
+ }
118
+
119
+ class MyDataUser
120
+ {
121
+ public void UseData(MyData myData)
122
+ {
123
+ myData.Data1 = "hogehoge"; //コンパイルを通したくない
124
+ Console.WriteLine(myData.Data1);
125
+ Console.WriteLine(myData.Data2);
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
41
131
  ### 自分で考えた実現方法
42
132
 
43
133
  * 全てのプロパティをgetのみとしたIReadOnlyMyDataインターフェースを定義し、MyDataに実装させる
@@ -49,4 +139,7 @@
49
139
  ### 別のアプローチについて
50
140
 
51
141
  DataContractSerializerを使ってsetをprivateにし、新規作成はコンストラクタ引数で行うようにすれば背景の問題は解消しそうな気がしていますが、xmlのデータ順が縛られる上、データクラスへの変更が大きいため二の足を踏んでいます。
52
- また背景に囚われずに一般論として質問のようなことが出来るか/どうやって行うか興味があるため質問させていただきました。
142
+ また背景に囚われずに一般論として質問のようなことが出来るか/どうやって行うか興味があるため質問させていただきました。
143
+
144
+ ### 補足情報(追記)
145
+ C# 7.2 / .NET4.6.1の環境を使用しています。