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

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

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

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

Q&A

解決済

3回答

329閲覧

Listで外部からアクセスできるインスタンスを作りたい

marvel

総合スコア13

C#

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

0グッド

0クリップ

投稿2018/04/01 14:04

List<T>をForm1で宣言し、Form2でListのインスタンスを作り値を入力・シリアル化します。
その後、Form3からXMLをロードしてForm2で作ったインスタンス(wind.member)にアクセスしようとしてもアクセスできません。また単純にインスタンスをpublicにすることもできませんでした。

クラスについてよく理解できていないので間違っていたらすみません。ソースコードを参照にしていただけらばなと思います。

よろしくお願いします。

c#

1     //Form1.cs 2 public const string FILENAME = @"D:\windmember.xml"; 3 4 public class member 5 { 6 public static int MemberNum; 7 public List<Person> people = new List<Person>(); 8 } 9 10 public class Person 11 { 12 public string Name; 13 public int num; 14 } 15 16     //Form2.cs 17 private void button1_Click(object sender, EventArgs e) 18 { 19 member.MemberNum += addnum; 20 member wind = new member(); 21 22 //wind.memberに要素を加える処理 23 24 XmlSerializer serializer = new XmlSerializer(typeof(member)); 25 FileStream fs = new FileStream(FILENAME, FileMode.Create); 26 serializer.Serialize(fs, wind); 27 fs.Close(); 28 29 } 30 31     //Form3 32     private void Form3_Load_1(object sender, EventArgs e) 33 { 34 XmlSerializer serializer = new XmlSerializer(typeof(member)); 35 FileStream fs = new FileStream(FILENAME, FileMode.Open); 36 member cls = (member)serializer.Deserialize(fs); 37 fs.Close(); 38 } 39 40 private void button1_Click(object sender, EventArgs e) 41 { 42 foreach (int num in people) //peopleが見つからない 43 { 44 45 }

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

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

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

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

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

guest

回答3

0

質問者様がやりたいことは、Listを色んなクラスから使えるようにしたいということであって
試行錯誤した結果、シリアライズ/デシリアライズをやってみたと言うことであれば…

memberを静的クラス(クラスおよびクラス内のすべてのフィールドメソッドにstaticを付ける)にすれば、外部からアクセスできるようになります。
ただし、下記の注意点があります。

  • 静的クラスは自動的に生成され、1つしか存在することができない(newできない)
  • 意味もなく多用することはおすすめできない。(理由は試行錯誤やWebで調べれば出てきます。)

C#

1//Member.cs 2public static class Member 3{ 4 public static int MemberNum; 5 public static List<Person> people = new List<Person>(); 6} 7 8//Person.cs 9public class Person 10{ 11 public string Name; 12 public int num; 13} 14 15 16 //Form2.cs 17 private void button1_Click(object sender, EventArgs e) 18 { 19 Member.MemberNum += 1; 20 Person person = new Person(); 21 person.Name = "test"; 22 person.num = 20; 23 24 //personの追加 25 Member.people.Add(person); 26 } 27 28     //Form3.cs 29     private void button1_Click(object sender, EventArgs e) 30 { 31 foreach (var person in Member.people) 32 { 33 MessageBox.Show(person.Name + "," + person.num); 34 } 35 }

投稿2018/04/01 15:20

RexiA7v

総合スコア112

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

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

marvel

2018/04/01 15:43

Listを様々なクラスからアクセスすることと同時にシリアライズする必要がありました。質問の仕方が悪くすみません staticも使いましたが、結局シリアライズする際にルート要素が見つからないとエラーを返されました。(コードの書き方が悪かったのかもしれませんが)
marvel

2018/04/01 15:59

Form3.cs、button1_Click内のpeopleにcls.が付いていないことと、デシリアライズしたものを異なるメソッドで使用しようとしていたことが問題だったようです。 参考にしたコードをそのままコピーしたのでデシリアライズした際、member.からcls.に変わることに気づけていませんでした。 おかげさまで解決することができました。ありがとうございます。
guest

0

ベストアンサー

Formが3つに分かれているため、Formを1つにしコードを流用してみました。
button1_ClickのPersonを一人生成あたりが既存のコードになかったため
このあたりの処理を追加すれば問題ないと思いますが、どのようにアクセスできないのでしょうか?
(表示されるエラーの内容があれば、質問時に記載しておくと回答がスムーズになります。)
知識不足等で見当違いのコードを書いていたとしても、やりたい事・やった事を具体的に書いておくと良いと思います。

C#

1public partial class Form1 : Form 2 { 3 private const string FILENAME = @"D:\windmember.xml"; 4 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 // ボタン1を押したときはシリアライズ 11 private void button1_Click(object sender, EventArgs e) 12 { 13 member.MemberNum += 1; 14 member wind = new member(); 15 16 // Personを一人生成 17 Person person = new Person(); 18 person.Name = "test"; 19 person.num = 20; 20 21 // peopleリストに追加 22 wind.people.Add(person); 23 24 XmlSerializer serializer = new XmlSerializer(typeof(member)); 25 FileStream fs = new FileStream(FILENAME, FileMode.Create); 26 serializer.Serialize(fs, wind); 27 fs.Close(); 28 29 MessageBox.Show("finish"); 30 } 31 32 // ボタン2を押したときはデシリアライズ 33 private void button2_Click(object sender, EventArgs e) 34 { 35 XmlSerializer serializer = new XmlSerializer(typeof(member)); 36 FileStream fs = new FileStream(FILENAME, FileMode.Open); 37 member cls = (member)serializer.Deserialize(fs); 38 fs.Close(); 39 40 MessageBox.Show(cls.people[0].Name + "," + cls.people[0].num); 41 } 42 43 public class member 44 { 45 public static int MemberNum; 46 public List<Person> people = new List<Person>(); 47 } 48 49 public class Person 50 { 51 public string Name; 52 public int num; 53 } 54 }

投稿2018/04/01 14:35

編集2018/04/01 14:39
RexiA7v

総合スコア112

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

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

marvel

2018/04/01 15:24

原因がわかりましたので、完全に解決次第またコメントします。 一応Personの一人生成あたりのコードは参考までに載せておきます。XMLには問題なく書き込めていたので省略してしまいました。 ```c# for (int i = 1; i <= addnum; ++i) //addnumは別のオブジェクトで取得済。 { Person obj = new Person(); obj.Name = ((TextBox)this.Controls[string.Format("textBox{0}", i)]).Text; obj.num= Decimal.ToInt32(((NumericUpDown)this.Controls[string.Format("numericUpDown{0}", i)]).Value); wind.people.Add(obj); } ```
guest

0

C#

1     //Form2.cs 2 private void button1_Click(object sender, EventArgs e) 3 { 4 member.MemberNum += addnum; 5 member wind = new member();

なんか意図がよーわかりませんが、

C#

1     //Form2.cs 2 private void button1_Click(object sender, EventArgs e) 3 { 4 member wind = new member(); 5 wind.MemberNum += addnum;

じゃないですか?
addnumもどこから来てるのか不明だし、ツッコミどころが多そうですが。。

投稿2018/04/01 14:31

y_waiwai

総合スコア87719

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

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

marvel

2018/04/01 14:53

ありがとうございます。 addnumについては質問した時点では不要だと考えていましたが、消し忘れてしまいました。 以後よく確認するようにします。すみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問