rksoftware

Visual Studio とか C# とかが好きです

C# 2.0 以降の新機能の確認 - C# 7.1 - 非同期 Main メソッド

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

非同期 Main メソッド

 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/main-and-command-args/#overview
 Main メソッドを async にできます。

static async Task Main(string[] args)
{
    var text = await new System.Net.Http.HttpClient().GetStringAsync("http://rksoftware.hatenablog.com/");

    Console.WriteLine(new string(text.Take(200).ToArray()));
}

C# 2.0 以降の新機能の確認 - C# 7.0 - 数値リテラルの表記の改善 (Literal improvements)

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

数値リテラルの表記の改善 (Literal improvements)

 https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-7#numeric-literal-syntax-improvements(英語)
 2進数表記でのリテラルを記述できる。数値リテラルの桁数などをわかりやすく記述できる。

int nenshu = 50_000_000;
Console.WriteLine($"年収 {nenshu} 億円");

int shoyo = 0b0100_0110_0101;
Console.WriteLine($"賞与 {shoyo} 万円");

C# 2.0 以降の新機能の確認 - C# 7.0 - 一般的な型での非同期メソッドの戻り値 (ValueTask)(Generalized async return types)

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

一般的な型での非同期メソッドの戻り値 (ValueTask)(Generalized async return types)

 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/async/async-return-types#generalized-async-return-types-and-valuetasktresult
 async 非同期メソッド内で非同期処理が必要である場所を通らなかった場合、Task オブジェクトを作らない事ができる。

static void Main(string[] args)
{
    int a = Func(true).Result;  // 非同期処理を通らないパターン
    int b = Func(false).Result; // 非同期処理を通るパターン
}

static async ValueTask<int> Func(bool b)
{
    if (b) return 0;
    await Task.Delay(1).ConfigureAwait(false);
    return 1;
}

C# 2.0 以降の新機能の確認 - C# 7.0 - throw 式 (Throw expressions)

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

throw 式 (Throw expressions)

 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/throw#the-throw-expression
 throw を、式およびステートメントとして使用できる。

class MyClass
{
    // コンストラクタ
    internal MyClass(string value) => _value = value ?? throw new ArgumentException();

    // プロパティ
    private string _value;
    internal string Value
    {
        get => _value;
        set => _value = value ?? throw new ArgumentException();
    }

    // メソッド
    internal string GetValue() => throw new ArgumentException();
    internal void SetValue(string value) => _value = value ?? throw new ArgumentException();
}

C# 2.0 以降の新機能の確認 - C# 7.0 - 式形式のメンバーの追加 (More expression bodied members)

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

式形式のメンバーの追加 (More expression bodied members)

 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members
 コンストラクター、ファイナライザー、プロパティの settergetter、メソッドを式で定義できる。

class MyClass
{
    // コンストラクターを式で宣言可能
    internal MyClass(string value) => _value = value;
    // ファイナライザーを式で宣言可能
    ~MyClass() => Value = null;

    // プロパティのアクセサーを式で宣言可能
    private string _value;
    internal string Value
    {
        get => _value;
        set => _value = value;
    }

    // メソッドを式で宣言可能
    public override bool Equals(object obj) => obj is MyClass c && this.Value == c.Value;
    public override int GetHashCode() => base.GetHashCode();
}

C# 2.0 以降の新機能の確認 - C# 7.0 - ローカル関数 (Local functions)

C# 2.0 以降の新機能を一つづつ確認していきます。
以前に一度行ったのですが、公式ドキュメント再編でリンク切れしているところを見つけてしまったので。今ならもっと簡潔なサンプルが欠けるところもあるだろうし、せっかくなので今もう一度確認して行きます。

ローカル関数 (Local functions)

 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/local-functions
 メソッド内でメソッドを定義できる。

class LocalFunctionSample
{
    void NewStyle()
    {   // ローカル関数
        // 関数呼び出し
        func(0);
        // 呼び出しより後方に書ける
        void func(int v)
        {
            Console.WriteLine(++v);
            if (v < 3)
            {
                // 自分自身を再起呼び出しできる
                func(v);
            }
        }
    }

    void OldStyle()
    {   // 以前のスタイル
        // 自分自身を再起呼び出しできないので、変数が必要
        Action<int> func = null;
        // 変数に関数を代入
        func = v =>
        {
            Console.WriteLine(++v);
            if (v < 3)
            {
            // 変数で関数を再起呼び出し
            func(v);
            }
        };
        // 呼び出しより前方で関数を書く必要がある
        // 関数呼び出し
        func(0);
    }
}