のにっき

【C#】修飾子ごとに出来る事 ※. private、public、static 編

今日、後輩に「staticって何ですか?」と聞かれて、激テンパったので調べてみました。
結果として、口で説明することは私には無理だ。とさじを投げたのですが、
各修飾子の挙動をまとめることで後輩に何とか説明できました。
ブログのネタになりそうでしたのでまとめます。

構文エラーで挙動を確認してみた

C#でクラス内に各修飾子の変数を定義し、クラスを跨いで 変数にアクセスした時に、構文エラーが出るものをまとめてみました

確認用コード

▼ 変数を定義したクラス

namespace WindowsFormsApp1
{
    class Cmn_Script
    {
        //テスト用クラス
        private string Hensu_Private;
        public string Hensu_Public;
        public static string Hensu_Static;

        //メソッドから変数をいじる用
        public void SetHensu_Public()
        {
            Hensu_Private = "";
            Hensu_Public = "";
            Hensu_Static = "";
        }
        public static void SetHensu_Static()
        {
            Hensu_Private = "";
            Hensu_Public = "";
            Hensu_Static = "";
        }
    }
}

▼ 変数をいじる関数を定義したクラス

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        // A)クラスを直接いじる
        private void Event_Test_A()
        {
            Cmn_Script.Hensu_Private = "";
            Cmn_Script.Hensu_Public = "";
            Cmn_Script.Hensu_Static = "";
        }
        // B)クラス型変数を作って中身をいじる   
        private void Event_Test_B()
        {
            Cmn_Script Cls_Set = new Cmn_Script();
            Cls_Set.Hensu_Private = "";
            Cls_Set.Hensu_Public = "";
            Cls_Set.Hensu_Static = "";
        }
        // C)クラス内メソッドを作って中身をいじる   
        private void Event_Test_C()
        {
            Cmn_Script.SetHensu_Public();
            Cmn_Script.SetHensu_Static();
            Cmn_Script Cls_Set = new Cmn_Script();
            Cls_Set.SetHensu_Public();
            Cls_Set.SetHensu_Static();
        }
    }
}

こんな感じでソースを組みました。
Windowsフォームアプリ内で作成したのでクラス名が変なのは気にしないでください。
同一namespace内の別クラスからアクセスしている。という事が重要です。

実際の構文エラー

エディターの画像をそのまま貼り付けます。

f:id:apuridasuo:20200717234954p:plain
図:エディター画像
画像のとなっている部分が構文エラーになっています。
構文エラーになるという事は、修飾子のルールにのっとっていない。という事です。
つまり、エラーの有無で修飾子の特性が分かってきます。

エラーから見える修飾子の特性

エラー情報から各修飾子の特性を見ていきます

①. Static(ソース上:SetHensu_Static)

Static変数は、「 A)クラスを直接いじる 」場合と、
同一クラスのメソッドからいじる 」場合にのみエラーになっていません。
つまり、Static変数の特性は
・同一クラスからのアクセスは可能
・クラスへ直接アクセスしてからのアクセス時は可能
という事です。
このおかげで、Static変数は大きな特性がありました。
クラス型の変数を作ろうが、クラスに直接アクセスしようが同じ値になる
という特性です。
他の修飾子の変数は、クラス型の変数(ソース上:Cls_Set)を作ると、
その変数ごとに値が変わっていくと思います。
Static変数はそれを許しません。
どんな状況でもアクセスできるけど、どんな状況でも同じ値になる
というのが特性の様です。

②. Private(ソース上:Hensu_Private)

Privateの変数を追ってみると、とても分かりやすい挙動になっています。
同一クラス内のメソッド以外からのアクセスは全てエラーになっています。
また、同一クラス内のメソッドでも
staticのメソッドのアクセスもエラーになっている点に注目です!
つまり、
同一クラス内からのみアクセス可能。かつ、
クラス型の変数を作れば、変数ごとに値も変わっていく
という特性になります。

③. Public(ソース上:Hensu_Public)

PublicはStaticとPrivateの自由な部分を併せ持った感じですね。
Staticのメソッド 」、「 A)クラスを直接いじる
つまり、
クラス型変数を作って、その中で変数をいじることで
クラス変数ごとに別々の値を持ち、自由にアクセスできる。

しかし、
自由に値を変えれるため、クラスを直接アクセスする方法は禁止されている。

以上です。
全然違う説明を行っていたら大変申し訳ございません。
素人の独学だと細かい知識がうっすらし過ぎていて恥ずかしい限りです。
違っている部分があれば、ご指摘いただけると
本当に勉強になりますので嬉しいです。