C# の特徴とプログラムの一般構造 学習

## 本記事について
Microsoft の Document [C# プログラミング ガイド](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/) 一部の学習記事です。
本記事で記載する内容は以下となります。

* C#(シー シャープ) 言語の特徴
* プログラムの一般構造
  * クラス
  * 構造体
  * 名前空間
  * インターフェース
  * デリゲート

## C#(シー シャープ) 言語の特徴
C#(シー シャープ)は、**シンプルなコンポーネント指向・タイプセーフなオブジェクト指向のプログラミング言語**であり、**共通型システム**を採用している。

具体的な内容を深ぼっていく。

### シンプルなコンポーネント指向
オブジェクト指向言語であるが、コンポーネント指向な設計でもある。
コンポーネント指向なので、自己完結型・自己記述型パッケージのソフトウェアサポートを提供していることが強み。
自己完結型パッケージは、各オペレーティングシステム(Linux, MacOS, Windows)で実行可能にして配布することができるため、環境依存がなくなる。
最近のソフトウェアは、マイクロサービス・用途に特化したコンポーネント単位で作成されることが多く、各オペレーティングシステム(Linux, MacOS, Windows)で実行できることが重要なため自己完結型パッケージをサポートしている。
コードをコンポーネント化する設計思想である。

### タイプセーフ
タイプセーフ（プログラムが型付けされている）なので、定義された有効な方法でのみ型にアクセスし、安全に実行ができる。
タイプセーフの確認タイミングは、JIT(Just In Time)コンパイル時に検査している。

* 初期化されていない変数の読み取りができない
* 配列範囲外のインデックス作成ができない
* チェックを行わない型のキャストができない
* etc..

### 共通型システム
[共通型システム](https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/common-type-system)

*1. .NET実装で多言語実行のためのフレームワークを確立する。*
共有言語ランタイムにおける型の宣言、管理方法を定義している。

*2. 型の厳密な規則と定義・開発に必要なライブラリの提供*
タイプセーフであり、システムパフォーマンスの高い実行を可能にした設計である。
C#のプリミティブ型は、1つのObject型から派生していて、すべての型が一貫した方法で管理されている。
クラス、構造体、インターフェース、デリゲート、クラス継承が可能であり、標準ライブラリもサポートしている。

## C# のプログラム一般構造
### クラス (Class)
Class は参照型である。
Class は、変数で宣言すると new 演算子で初期化するまで、nullが格納されている。
new 演算子で初期化すると、ヒープ上でメモリ割り当てが行われて参照可能になる。

SampleClass.cs

```C#
using System;
namespace study.Namespace
{
    public class SampleClass
    {
        public SampleClass()
        {
        }
        
        public void Hello()
        {
            Console.WriteLine("Hello world C#");
        }
    }
}

```

### 構造体 (Struct)
C#の構造体には、値のセマンティクスがある。
小さなデータサイズ かつ Integer, Bool, String, DateTime のインスタンスを保持することを推奨している。
値のセマンティクスなので、クラス型変数を保持した場合は型のインスタンスが含まれることになる。

SampleStruct.cs

```C#
using System;

namespace study.Struct
{
    public struct SampleStruct
    {
        public SampleStruct(double x, double y)
        {
            X = x;
            Y = y;
        }

        private double X { get; }
        private double Y { get; }

        public override string ToString() => $"({X}, {Y})";

        public void Output()
        {
            Console.WriteLine(ToString());
        }
    }
}
```

### 名前空間 (Namespace)
名前空間でクラス、インターフェース、構造体等を整理する。

* ドット(.) 演算子で Nested を定義する
* using ディレクティブによって、クラスごとに定義する必要がなくなる。
* `global` 名前空間は、ルート名前空間として利用できる。

### インターフェース (Interface)
他の言語と同様で、複数の実装クラスによる動作を提供することができる。
非抽象クラス または 構造体 で実装する必要がある。

ISampleInterface.cs

```C#
namespace study.Interface
{
    public interface ISampleInterface
    {
        void Hello();

        bool IsOk();
    }
}
```

SampleInterface.cs

```C#
using System;

namespace study.Interface
{
    public class SampleInterface : ISampleInterface
    {
        public void Hello()
        {
            Console.WriteLine("Hello Interface");
        }

        public bool IsOk()
        {
            return true;
        }
    }
}
```

### デリゲート (Delegate)
デリゲートは、メソッドへの参照をあわわすことができる型であり、イベントハンドラ等で利用する。
`getAge` メソッド と `age` デリゲート変数 がある場合、age = getAge という意味を持たせるのがデリゲートである。

SampleDelegate.cs

```C#
using System;

namespace study.Delegate
{
    public class SampleDelegate
    {
        public delegate void AgeDelegate(int age);

        public static void AgeOutput(int age)
        {
            Console.WriteLine("Call Delegate", age);
        }
    }
}
```

## Mainプログラムで実行
Program.cs

```C#
using System;
using study.Delegate;
using study.Interface;
using study.Namespace;
using study.Struct;

namespace study
{
    public static class Program
    {
        public static void Main()
        {
            // Class instance
            SampleClass sampleClass = new SampleClass();
            sampleClass.Hello();

            // Struct
            SampleStruct sampleStruct = new SampleStruct(1.0, 2.0);
            sampleStruct.Output();
            
            // Interface
            ISampleInterface sampleInterface = new SampleInterface();
            sampleInterface.Hello();
            
            // Delegate
            int age = 15;
            SampleDelegate.AgeDelegate ageDelegate = SampleDelegate.AgeOutput;
            ageDelegate(age);
        }
    }
}
```

## 所感
型、定義が厳密であり、個人的には非常に好きな言語であった。
普段は Java, Golang を利用していることもあることから、学習もしやすい言語であった。
(Javaを利用している人には、学習コストが低い。)

何より良いと感じた点は、Microsoft の Document が充実していること。
C#によるプログラミングの学習・C#の基礎・C#新機能・C#リファレンス 等、学習するのに詳細まで記載してあるドキュメントがあることは強みの一つと感じた。