DOBON.NET DOBON.NETプログラミング掲示板過去ログ

構造体の配列から値を設定・取得について

環境/言語:[C#]
分類:[.NET]

おせわになっております。

構造体の配列から値を設定・取得したのですが、どのように記述
すればよいのでしょうか?

下記のように構造体を定義したのですが、構造体AAAのメンバbからは、
BBBのメンバにアクセスできないです。。。

ご教授お願いします。


/*--- Form1 ---*/
            Form2 f2 = new Form2();
            f2.Show();
            Form3 f3 = new Form3();
            f3.Show();

/*--- Form2 ---*/
        private void button1_Click(object sender, EventArgs e)
        {
            Class1.AAA.a = 1;
            // AAA.bの配列にも値を入れたいです。。。
         }   
/*--- Form3 ---*/
        private void button1_Click(object sender, EventArgs e)
        {
            richTextBox1.AppendText(Convert.ToString(Class1.AAA.a));
            // AAA.bに値が設定できたら取得したいです。。。
         }

/*--- Class1 ---*/
    class Class1
    {
        public struct AAA
        {
            static int _a;
            public static int a
            {
                get { return _a; }
                set { _a = value; }
            }

            static BBB[] _b = new BBB[3];
            public static BBB[] b
            {
                get { return _b; }
                set { _b = value; }
            }
        }

        public struct BBB
        {
            static int _c;
            public static int c
            {
                get { return _c; }
                set { _c = value; }
            }

            static int _d;
            public static int d
            {
                get { return _d; }
                set { _d = value; }
            }
        }
    }
> 構造体AAAのメンバbからは、
> BBBのメンバにアクセスできないです。。。
bは構造体ではなく構造体の配列ですからb[0].cと添え字をつけないと触れないと思いますが、
そういうことではなく、ですか?

> bは構造体ではなく構造体の配列ですからb[0].cと添え字をつけないと触れないと思いますが、
> そういうことではなく、ですか?

Form2に下記のように宣言すると
 Class1.AAA.b[0].c = 1;
”インスタンス参照で性的メンバ”WindowsApplication2.Class1.BBB.get'に
アクセスできません。typenameを代わりに使用してください。"
とコンパイルエラーがでるのですが、コンパイルエラーの意味がいまいちわか
らないのですが。。。なにが問題なのでしょうか?
> インスタンス参照で静的メンバ”WindowsApplication2.Class1.BBB.get'に
> アクセスできません。
「static」つけてるせいかと。
staticは、インスタンス(オブジェクト)に触れる必要のない共通の処理の場合にのみ
使ってください。
この場合、インスタンス(オブジェクト)のメンバにアクセスできないと困るわけで…
全部static要りません。
2006/07/17(Mon) 22:58:34 編集(投稿者)

って、あれ?

よく見たら、「Class1.AAA.a = 1;」って…
クラスそのものにセットしたいんですか?
「
  Class1 cl1=new Class1();
  しておいて、

  cl1.AAA.a = 1;
」
とかせずに使いたいんですか。
それだとClass1型のデータをひとつしか使えませんが。

「Class1」でBBB型の配列を使用しているんですから、BBB型の3枠があるわけで、
「BBBそのもの」のメンバに値を入れてしまうことはできませんよね。
BBBの方は、staticはつけてはいけません。
> BBBの方は、staticはつけてはいけません。

staticを使わない場合は、Form2で設定した値をForm3で
使う場合はプロパティを使えばよいのでしょうか?
まず…
とりあえず、f2でb[0]のcにアクセスするには
「this.textBox1.Text=Class1.AAA.b[0].c.ToString();」
でできますね。
(私はインスタンスを作らないでクラスを使うのは好きじゃないですが。できることはできます。)

> staticを使わない場合は、Form2で設定した値をForm3で
> 使う場合はプロパティを使えばよいのでしょうか?
連携するにはお互い経路がないといけないわけですからね。
何らかの経路を用意する必要があります。

ちょっとClass1自体変えましたが、
良いか悪いかは別として…f2のボックスでセットした値をf3のボックスに受け取る例。
(Form1のインスタンスを連携の仲介として。)
…何か適当ですが。

/*【Class1】*/
public class Class1
{
    public AAA aaa = new AAA();
    public class AAA
    {
        int _a;
        public int a
        {
            get { return _a; }
            set { _a = value; }
        }

        BBB[] _b=new BBB[3];
        public BBB[] b
        {
            get { return _b; }
            set { _b = value; }
        }
    }
    public struct BBB
    {
        int _c;
        public int c
        {
            get { return _c; }
            set { _c = value; }
        }

        int _d;
        public int d
        {
            get { return _d; }
            set { _d = value; }
        }
    }
}


/*【Form1】*/
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    public Class1 sharedata = new Class1();

    private void Form1_Load(object sender, EventArgs e)
    {
        Form2 f2 = new Form2();
        Form3 f3 = new Form3();
        f2.setManagerForm(this);
        f3.setManagerForm(this);
        f2.Show();
        f3.Show();
    }
}

/*【Form2】*/
public partial class Form2 : Form
{
    private Form1 managerForm;
    public void setManagerForm(Form1 tmpManagerForm)
    {
        this.managerForm = tmpManagerForm;
    }
    public Form2()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        this.managerForm.sharedata.aaa.b[0].c = int.Parse(this.textBox1.Text);
    }
}

/*【Form3】*/
public partial class Form3 : Form
{
    private Form1 managerForm;
    public void setManagerForm(Form1 tmpManagerForm)
    {
        this.managerForm = tmpManagerForm;
    }
    public Form3()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        this.textBox1.Text = this.managerForm.sharedata.aaa.b[0].c.ToString();
    }
}
ありがとうございます。
教えて頂いたやり方で解決することができました。

たびたびで申し訳ないのですが、もう1点質問させてください。
構造体"BBB"のメンバに配列(int[] intArray)というものが
あった場合はどのように記述すればよいのでしょうか?
(BBBをclassにして行ってみたのですが、"オブジェクト参照が
オブジェクト、インスタンスに指定されていません"の
例外がForm2で発生します。。。
一応Class1でBBBをnewしているのですがうまくいきません。。。)

> (私はインスタンスを作らないでクラスを使うのは好きじゃないですが。できることはできます。)
C#をはじめて数ヶ月なので。。。上記のような構造体の値を別クラスで設定・取得
といったものの一般的は実装方法をご教授いただればうれしいです。
構造体と違ってクラスはnewをしないと使えないのは分かると思いますが、
クラス型のものを配列で用意する場合、配列の確保と、
それぞれの要素へのインスタンスの割付という2ステップが必要です。
つまりBBBをクラスに変更して用意した場合、
BBB[] _b=new BBB[3];では配列でBBB型のための枠を確保しただけで、
_b[0]、_b[1]、…にインスタンスがセットされるわけではないので、
BBB[] _b=new BBB[3];
だけでなく、
_b[0]=new BBB();
_b[1]=new BBB();
_b[2]=new BBB();
を行う必要があります。
ただし、これは変数宣言の場所では行えないので、
AAAのクラス内に「コンストラクタ」を用意してそこで行います。

例えば以下のようにします。

const int COLNUMBER=3;        //変えやすいようにしただけですよ。
BBB[] _b;
public BBB[] b
{
    get { return _b; }
    set { _b = value; }
}
public AAA()
{
    _b = new BBB[COLNUMBER];
    for (int col_num = 0; col_num < _b.Length; col_num++)
    {
        _b[col_num] = new BBB();
    }
}
解決できました。

長々と付き合った頂いてありがとうございます。
解決済み!
お世話になっております。

一度解決したといったのですが、再度質問させてください。。。

フォームではなく、クラスで値を設定しようとした場合、設定時に
「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
の例外が発生します。どうすれば回避できるのかご教授お願いします。

■16702で教えて頂いたやり方で
【Form1】で

            Class2 c2 = new Class2();
            c2.test();

として、
【Form2】の代わりに下記のClass2を作成しました。

    class Class2
    {
        private Form1 managerForm;
        public void setManagerForm(Form1 tmpManagerForm)
        {
            this.managerForm = tmpManagerForm;
        }

        public void test()
        {
      // ↓の箇所で「オブジェクト参照がオブジェクト 
      // インスタンスに設定されていません。」
      // の例外が発生します。
            this.managerForm.sharedata.aaa.b[0].c = 1;
        }
    }
すみません。。。解決しました。

            Class2 c2 = new Class2();
      c2.setManagerForm(this);
            c2.test();

で大丈夫でした。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板