11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C#9.0 マイナーだけど有用な機能

Last updated at Posted at 2020-12-21

ついに登場したC#9.0ですが、皆さんはもう使いこなしていますか?
9.0の目玉機能といえば、Record型やSource Generatorだと思います。ですが、ほかにも便利な機能が追加されたので個人的にいいなと思ったものをピックアップして紹介したいと思います!
NEXT SCAPE Advent Calender14日目の記事でもC#9.0について紹介しているのでぜひ見てみて下さい。

##パターン マッチングの拡張機能
パターンマッチングの機能が強化されました。
中でもnotはかなり使える場面が多いでしょう。

        void NotPattern(object x)
        {
            if (x is null) return; //C# 8.0まで
            if (x is not null) return; //C# 9.0からnotが使える! 
        }

andorも使えるようになりました。

        static void OrAndPattern(object x)
        {
            if (x is double or string) return;
            if (x is int and 1) Console.WriteLine("intの1");
        }

switch式と組み合わせて以下のように書けるようにもなりました。例があまりよくないですが、andornotとも組み合わせることができます。

        static string Age(int age) => age switch
        {
            <= 12 => "小人",
            <= 18 => "中人",
            60 or 77 or 88 => "めでたい",
            >= 30 and < 40 and not 31 => "31歳以外の30代",
            _ => "大人"
        };

##ラムダ ディスカード パラメーター
ラムダ式を書くときにパラメーターを使わない場合がかなりあると思います。.NETのライブラリのイベントは大体(object sender,EventArgs e)で定義されていますしね。
**使わないという意図を明示して書きたい。**そんなあなたにいい機能が入りました。
パラメーター定義をすべてアンダースコアにすることで、未使用ではなく破棄されることになります。

        private static event EventHandler hogeevent;

        static void EventHandle()
        {
            hogeevent += (_, _) => //すべてのパラメーターを_にすることでラムダのスコープ内で使えなくなります。
            {
                Console.WriteLine("");
            };
        }

##静的匿名関数
最近のC#はパフォーマンス改善と、といかに状態を排除するコードを書けるようにするかにご執心です。個人的にはいいことだと思います。
LINQに渡すラムダ式等でラムダ式の外の変数を使おうとするとコピーが発生していました。

        static void StaticAnonymousFunction()
        {
            var p = 1; //定数のように利用する想定
            var data = Enumerable.Range(1, 10).Select(x => x * p).ToArray(); //pがヒープにコピーされる。
        }

以下のように、ラムダ式の直前にstaticをつけることで無駄にヒープを使うことを回避できます。

        static void StaticAnonymousFunction()
        {
            const int p = 1; //定数のように利用する想定
            var data = Enumerable.Range(1, 10).Select(static x => x * p).ToArray(); //ヒープアロケーションを回避
        }

ILを見ると上の例ではラムダ式と一緒に作られるクラスのフィールドに1をセットしているのがわかります。
下の例では単純に定数の1をスタックにプッシュするようになります。
パフォーマンスを気にしたい場合は検討してみましょう。

##最後に
.NET 5は長期サポートされません。お仕事で使う方は.NET 6への移行を視野に使いましょう。
自分も早くお仕事で使いたいな。

11
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?