C#初心者が書くC#入門TIPS

# 概要
- 他のプログラミング言語は触ったことある人が、知らなそうなことを実例を通して簡潔に書きます。(詳しくはMSDNとか見てください)
- C#の基本的なこと(変数、条件分岐、ループ処理、クラス)は書きません。
- 私もC#の初心者なので、内容の保証はしません。(わかる人フィードバックください)
- 半分以上、個人的メモです。

# ジェネリッククラス(ジェネリックメソッド)
簡単にいうと引数に型を指定できるクラス(メソッド)。

よく使うListやDictionaryもジェネリッククラスです。

ここではジェネリッククラスについて説明します。メソッドも似たような感じです。

例えばこんなクラス(プッシュだけできる整数のスタック)があったとする。

```cs:
class IntPushStack
{
    int cnt = 0;
    int[] stack = new int[100];

    public void Push(int val)
    {
        stack[cnt] = val;
        cnt++;
    }

    public void WriteState()
    {
        for (var i = 0; i < cnt; i++)
        {
            Console.Write(stack[i] + " ");
        }
        Console.WriteLine();
    }
}
```

こんな感じで実行する。

```cs:
class Program
{
    static void Main(string[] args)
    {
        IntPushStack s = new IntPushStack();
        s.Push(1);
        s.Push(2);
        s.Push(3);
        s.WriteState(); // -> 1 2 3
    }

}
```

「このクラス(IntPushStack)をdoubleもstringも使えるようにしたい」としたときに、
似たようにDoublePushStackやStringPushStackをコピペするのは冗長で無駄だ。

そんなときにジェネリッククラスを使う。
こんな感じ(```<T>```)で書くと、型を引数にし、クラスの記述内で型として使える。

```cs:
class PushStack<T>
{
    int cnt = 0;
    T[] stack = new T[100];

    public void Push(T val)
    {
        stack[cnt] = val;
        cnt++;
    }

    public void WriteState()
    {
        for (var i = 0; i < cnt; i++)
        {
            Console.Write(stack[i] + " ");
        }
        Console.WriteLine();
    }
}
```

こんな感じで実行する。

```cs:
class Program
{
    static void Main(string[] args)
    {
        PushStack<int> intStack = new PushStack<int>();
        intStack.Push(1);
        intStack.Push(2);
        intStack.Push(3);
        intStack.WriteState(); // -> 1 2 3

        PushStack<string> stringStack = new PushStack<string>();
        stringStack.Push("a");
        stringStack.Push("b");
        stringStack.Push("c");
        stringStack.WriteState(); // -> a b c
    }
}
```

便利便利。

ただし、型が不定なので、どのようなメソッドを使えるかかわからない。
そんな時につけるのが型パラメータの制約。

詳しくは[型パラメーターの制約 (C# プログラミング ガイド) | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters)


# LINQ
LINQ(読み方は「リンク」)は、foreachのすごい版みたいな解釈でいいらしいです。
[はじめての LINQ - Qiita](https://qiita.com/nskydiving/items/c9c47c1e48ea365f8995)がとても良記事なので参照ください。
LINQの実行タイミングとかを把握してると、後で痛い目見なくて済むと思います。(小学生並の感想)

```cs:
static void Main(string[] args)
{
    string[] colors = { "red", "yellow", "blue" };
    var query = from name in colors select new { Name = name, Len = name.Length, UpName = name.ToUpper() };

    foreach (var n in query)
    {
        Console.WriteLine(n.Name + " " + n.Len + " " + n.UpName);
    }
    // ->
    // red 3 RED
    // yellow 6 YELLOW
    // blue 4 BLUE
}
```

# ラムダ式

百聞は一見に如かずということで、実例です。
ラムダ式はインラインコードを簡潔に書くためのものらしい。
まだよく理解していないので、参考にしたページを載せておきます。

- [C# 今更ですが、ラムダ式 - Qiita](https://qiita.com/rawr/items/11790e9ea08a29d028a4)
- [ラムダ式 - C# 入門](http://csharp.keicode.com/basic/lambda-expressions.php)

```cs:
Func<int, int> square = 
Console.WriteLine(square(1)); // -> 1
Console.WriteLine(square(2)); // -> 4
Console.WriteLine(square(3)); // -> 8
Console.WriteLine(square(4)); // -> 16
Console.WriteLine(x => x * x); // -> 16
```

```
int[] num = { 1, 2, 3, 4, 5 };
var squaredNum = num.Select(x => x * x);

foreach(var x in squaredNum)
{
    Console.WriteLine(x);
}
// ->
// 1
// 4
// 9
// 16
// 25
```

# Null許容型、Null条件演算子、Null合体演算子
「?」とか「??」とか出てきたら、だいたいこいつです。
値がNullとかになるときにif文とか型検査とかいちいちやらなくても簡潔に書けるようになります。

以下のサイトがわかりやすいです。
[【ワテのC#講座】 int?はNull許容型、ナンチャラ?はNull条件演算子、??はNull合体演算子【ヌル三兄弟】](https://www.wareko.jp/blog/post-19919)

# その他
随時、追加予定