C#やモバイルアプリ関係のログ

C#やXamarin、スマートフォンアプリのことを書いておきたいと思います

C# モダンな書き方で引っ掛かりそうなところのまとめ

ほかの言語も同じですが、C#にはバージョンがあります。現在のC#のバージョンはVisual Studio 2017でC#7。Visual Studio 2019でC#8になるでしょうか。

C#のソースを読んでいる見慣れない構文が出てくるかと思います。バージョンが上がって知らない構文が増えているわけです。

Xamarinのサンプルソース読むにも出てくるので本記事でそういった人向けに直感的にわからなさそうなものを列挙したいと思います。

列挙は独断と偏見で選んでいます。本記事になくて、検索しようにも構文がわからないとか検索キーワードすらわからないかと思います。

そういうときは↓のサイトが非常に素晴らしいです。 ufcpp.net C#の最新のバージョンから新機能を見てけばいずれ疑問は解消するでしょう。

ラムダ式

そこまで(多分)新しいわけでもなく、また非常に便利です。delegateやeventhandlerというものを使ったことがない人にはなじみがない概念かもしれません。

自作サンプルです。
github.com

関数を変数として扱えます。そして、ラムダ式は変数に関数を代入する際の関数の書き方の一つであると思ってください。推論で引数の型(intとかstring)を省略できます。引数を囲む()も省略できます。

クラス内の関数定義で1行で書ききれる内容なら関数の定義にもラムダ式を利用できます。getter/setterにも利用できます。

    class Program
    {
        public string Age(int age) => age + "歳";
    }

とりあえず、なんとなく慣れてください。

Action Func

関数を変数として扱えます。パラメータの代入で右側がラムダ式とすると、左側のパラメータの型がActionやFuncとなります。

string hoge = "hogehoge!";

//代入
Action<string> a = s => Console.WriteLine($"This is {s}");

//実行
a("Action");

//代入
Func<string> f = () => "This is Func";
//実行
string isThis = f();

//代入
Func<string, string> ff = s => {
s = s + "<string, string>";
return $"This is {s}";
};

ActionとFuncはPLSQLのファンクションとプロシージャのようなものです。戻り値があるかないかの違いです。ジェネリックで引数と戻り値の型の指定がいります。{}で囲むと複数行書けます。

null 条件演算子

オブジェクトが関数を実行する際に?がついていることがあります。

Cat?.Eat("マグロ");

これは下記のようなものです。

if(Cat != null){
   Cat.Eat("マグロ");
}

タプル

DBでいうところのレコードに当たる概念です。

限定的な利用の変数の入れ物のクラスを一々定義しなくてもいいものになります。便利です。

class Program
{
    static void Main(string[] args)
    {
        var (name, age) = GetMe();
        Console.WriteLine($"{name} {age}歳");

        //取得不要な場合は_としてください
        var (name2, _) = GetMe();
        Console.WriteLine($"{name2}歳");

        Console.Read();
    }

    static (string name , int age) GetMe()
    {
        string name = "ちばらき 太郎";
        int age = 31;

        return (name, age);
    }
}

ローカル関数

関数の中に関数をかけます。関数の中のローカル変数をそのまま使えて便利です。

static void Main(string[] args)
{
    int age = 87;

    void WriteLine(string s)
    {
        Console.WriteLine($"{age}歳 {s}");
    }

    switch (age)
    {
        case int i when i <= 20:
            {
                WriteLine("若い!");
                break;
            }
        case int i when i > 20:
            {
                WriteLine("若くない!");
                break;
            }
    }

    Console.Read();
}