C#Windowsアプリで、独立したクラス間での値の受け渡し

タグの編集
投稿者 kojiro  (社会人) 投稿日時 2024/4/24 10:42:10
いつも、お世話になっております。
独立したクラス間での値の受け渡しをしたいのですが、方法をご教示ください。

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public  class class1
        {
            private string con;
            public string? CON
            {
                get { return this.con; }
                set { this.con = value; }
            }


        }
        private void button1_Click(object sender, EventArgs e)
        {
            class1 test = new class1();
            test.CON = "2";


        }

        private void button2_Click(object sender, EventArgs e)
        {
            class1 test2;
            string value = test2.CON.;
        }
    }

 

 class1 test2のtest2がエラーで
ここでは'test2'はnullではありません。
CS8062:null参照があるものの逆参照です。
CS0165:未割り当てのローカル変数'test2'が使用されました。
です。
投稿者 とくま  (社会人) 投稿日時 2024/4/24 11:54:43
変数のスコープの話は、ほとんどの入門本で最初の10ページ以内には書いてあるような基本ですが、
改めて見なおすと、VB中学校のサンプルでは、最初のうちは一つの関数内に収まる処理で済ましているんですね。
使われ始めるのはこの辺。
https://www.umayadia.com/CSStandard/s014BoundBall1.htm#A2_2
4.変数のスコープ
4-2.変数の適用範囲
まで読み進めて下さい。

関数の外側で宣言します。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public  class class1
        {
            private string con;
            public string? CON
            {
                get { return this.con; }
                set { this.con = value; }
            }
        }

        private class1 test = null;

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.test == null)
            {
                this.test = new class1();
                this.test.CON = "2";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.test == null)
            {
                MessageBox.Show("まだ初期化されていません");
            }
            else
            {
                string value = this.test.CON;
            }
        }
    }

投稿者 kojiro  (社会人) 投稿日時 2024/4/24 13:46:40
示されたコードは、正常に動作しました。
ただ、VSで、string value = this.test.CON の部分のthis.test.CONが緑波線です。無視してもよいですね?
投稿者 とくま  (社会人) 投稿日時 2024/4/24 16:54:57
>ただ、VSで、string value = this.test.CON の部分のthis.test.CONが緑波線です。無視してもよいですね?
質問文のコードで型が揃っていなかったのでそのままにしています。
正しいほうに統一すればよいのでは?
投稿者 kojiro  (社会人) 投稿日時 2024/4/24 23:15:59
var にしたら、波線は、消えましたが、なぜなのか。よく見ると、ほかの箇所にも波線があるようです。
 
namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public  class class1
        {
            private string con;    //conが波線->CS8618: null非許容のフィールドとして’CON'には、コンストラクター終了時にnull以外の値が入っていなければならない。フィールドをnull許容として宣言することを検討してください。とのことです。
            public string? CON
            {
                get { return this.con; }
                set { this.con = value; }  //valueに波線 CS8601 null参照代入の可能性があります。
            }
        }
        private class1 test = null;  //nullに波線 CS8625:nullリテラルをnull参照代入に変換できません
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.test == null)
            {
                this.test = new class1();
                this.test.CON = "2";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.test == null)
            {
                MessageBox.Show("まだ初期化さrていません");
            }
            else
            {
                string value = this.test.CON;  //stringをvarに変えたら、this.test.CONの波線が消えました
                MessageBox.Show(value);
            }
        }
    }
}
 

以上のように、波線があります。
投稿者 とくま  (社会人) 投稿日時 2024/4/25 08:22:12
文字列型と、文字列のNull許容型を混ぜて使っているからです。
Null許容型を使っている理由を教えてください。
投稿者 kojiro  (社会人) 投稿日時 2024/4/25 09:23:41


以下のように訂正して、波線がなくなりました。
以下のように訂正して波線がなくなりました。
 
namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        
        
        
        public  class class1
        {
            public string? CON { get; set; }


        }

        private class1? test = null;
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.test == null)
            {
                this.test = new class1();
                this.test.CON = "2";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.test == null)
            {
                MessageBox.Show("まだ初期化さrていません");
            }
            else
            {
                var value = this.test.CON;
                MessageBox.Show(value);
            }


        }
    }
}
 

ありがとうございました。