電気系プログラミングガチ素人学生がC#のクラスを勉強する話　６日目 ~クラスメンバー、シングルトン、静的コンストラクター~

#まえがき
このレポートは「独習C＃」で学んだ内容をSkype勉強会での活動日誌として、「書面としてアウトプットする」こと、「電気系の学生の成果物を作るための意識高い系(笑)のレポート」です。完全初心者なので、勉強会参加者の先輩たちから様々なツッコミを頂きながら書いております。それゆえに先輩たちの目から外れた誤字脱字等ございますが、ぜひともツッコミいただいて、私の勉強にさせていただければと思います。

今回は完全な個人戦でやってみます。就活の合間に勉強も忘れてはいけませんし（とってつけたような意識高い系属性）

#クラスメソッド・クラスフィールド　＝　クラスメンバー
* インスタンスを生成しなくても、直接クラスから呼び出せるフィールドのこと。
* 静的メソッド、静的フィールド、staticメソッドなどとも

# クラスメソッドの作り方
メソッド定義にstatic修飾子をつけるだけ。具体的例を書きます

```C#
using System;

namespace class_practice
{
    class Figure{
        public static void GetTriangleArea(int width, int height){//これが静的メソッド
            Console.WriteLine($"三角形の面積は{width * height/2}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //string [] input = Console.ReadLine().Split(' ');//入力メソッドを今回は用意（鈍ってしまわぬように）
            Figure.GetTriangleArea(10,20/*int.Parse(input[0]),int.Parse(input[1])*/);
        }
    }
}
```

実行結果は以下のようになりました

```
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
三角形の面積は100
```


##注意点
###1.クラスメソッドでは、変数thisは使えない
現在のインスタンスを参照するためのよく使われる変数である、thisですが、インスタンスそのものが使われていないため、この変数は使えません。

###2.クラスメソッドではオブジェクト経由では呼び出さない
このような呼び出し方ができないってことです。（インスタンス化してないからそらそうよね）

```
var f = new Figure();
f.GetTriangleArea(10,20);
```

#クラスフィールドの作り方
以下のようにコードを書きました。書き方は、やはり、クラスメソッドとほぼ同じ書き方。

```C#
using System;

namespace classfield
{
    class Figure{

        public static double Pi = 3.14;
        public static void GetCircleArea(double r){
            Console.WriteLine($"円の面積は{r*r*Pi}");//これってmathメソッド使えるのだろうか
        }        
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Figure.Pi);
            Figure.GetCircleArea(5);
        }
    }
}
```

#シングルトン
クラスのインスタンスを一つにしか生成できないようにするための機能です。以下にコードを書いて実行してみます

```C#
using System;

namespace singleton
{
    class Mysingleton {
        private static Mysingleton instance = new Mysingleton();

        private Mysingleton(){ }

        //あらかじめ用意しておいたインスタンスを取得
        public static Mysingleton Instance{
            get{
                return instance;
            }
        }

        public string x = "hello";
        
        
    }
    class Program
    {
        static void Main(string[] args)
        {   
            var f = Mysingleton.Instance;
            var g = Mysingleton.Instance;//このインスタンスは作られてない

            f.x = "こんにちは";//参照先が静的（同じ所を指している）なため
            Console.WriteLine(g.x); 
            
        }
    }
}
```

実行結果は以下のようになります。

```
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
こんにちは
```

生成されたインスタンスが一つしか生成されない＝参照先は一つのみということになるため、一度書換えがあれば、
参照する際は書換えたデータが参照されます。

#クラス定数
内容の書き込みを防ぐことができる（読み取り専用）のフィールドを作ることができます。

```C#
using System;

namespace classcon
{
    class Myapp{
        public static  readonly string Title = "C＃";
    }
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Myapp.Title);
            //Myapp.Title="本気で覚えるC#";
//これをコメントアウトしないと、エラーが起こる（読み取り専用のため）
        }
    }
}
```

出力は以下のようになりました。

```
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
C＃

```

以下のようなコードに書き換えも可能です。

```
public const string Title = "C#";
```

ただし、細かな違いがあります。
色々まとめると、本当に将来値が変更されない限りはreadonlyを使う方がベターと覚えておいて差し支えなさそうです。
ただし、以下の場合は動作します。

```C#
using System;

namespace Readonly
{

    class Program
    {
        public static readonly int [] Values = {1,2,3};
        static void Main(string[] args)
        {
            //Values = new[] {10,20,30};
            //再代入は不可。フィールド初期化子、コンストラクターでのみ初期化可能なため
            Values[0] = 15;
//こちらは実行可能。

            foreach(var s in Values){//本当に値が書き換わったのか確認する
            Console.WriteLine(s);
            }
        }
    }
}
```
実行した結果はこうなりました

```
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
15
2
3
```
ちゃんと書き換わっていますね！。

#静的コンストラクター
一度だけ実行されるコンストラクターのこと。
以下のようなコードを書くと、

```C#
using System;

namespace constructor
{
    class Messeage{
        int number;

        static Messeage(){
            Console.WriteLine("静的コンストラクター");
        }
        public Messeage(int number){
            this.number=number;
            Console.WriteLine($"通常のコンストラクター{number}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            var m1 = new Messeage(1);//静的コンストラクターも実行
            var m2 = new Messeage(2);//静的コンストラクターは実行されない
        }
    }
}
```

そのため、以下のような実行結果になりました。

```
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
静的コンストラクター
通常のコンストラクター1
通常のコンストラクター2
```

#あとがき
引数ってなんでひきすうって読むんだろうと研究室の間で話題でした。
プログラマあるあるみたいなものなんでしょうか笑

インターネットの速度不足は深刻なので、稼げるようになったら光を引きたいです（切望）