C# のヒントとコツ - パート 3


これは、以下のリンクで見つけることができる C# のヒントとコツのパート 3 です.

パート1:
パート2:

この記事では、以下について説明します.
  • 非同期メイン
  • タプル
  • クラスの値の等価性

  • YouTubeでフルビデオを見ることができます


    ソース コードは GitHub で入手できます.
    https://github.com/mohamadlawand087/v35-ctte3

    非同期メイン



    これにより、非同期ワードをメイン エントリ ポイントに追加できるようになります.

    メインメソッドから非同期メソッドを実行したい場合、以前はメインメソッドを待つことができませんでした.それを機能させるには、多くの配線を行う必要があります

    そのため、以前はこのようなものが必要です

    static void Main(string[] args)
    {
    
        // Old implementation - utilise the Async method
        var result = DoAsyncWork().GetAwaiter().GetResult();
    
        Console.WriteLine(result.ToString());
    }
    
    // Have an async method
    private static async Task<string> DoAsyncWork()
    {
        return await new HttpClient().GetStringAsync("https://docs.microsoft.com");
    }
    


    新しい実装

    static async Task Main(string[] args)
    {
        // New implementation -  Direct call to async 
       var res =  await new HttpClient().GetStringAsync("https://docs.microsoft.com");
       Console.WriteLine(res.ToString());
    }
    


    タプル



    データを表すために使用される軽い待機シンテックス.タプルを使用すると、クラスとレコードを持つ複雑さがなくなります.タプルを使用して、複数のフィールドを持つ単純なデータ構造を定義できます.

    2種類あります
  • 名前タプル
  • 名前のないタプル

  • 軽量の構文ですが、利用できる非常に強力な機能を備えています

    フィールドの名前を指定する名前付きタプルなので、name 変数を宣言します.フィールドの名前を指定したので、タプルを利用するときにそれを使用して参照できます

    // Name Tuple
    var named = (FirstName: "Mohamad", LastName: "Lawand");
    Console.WriteLine($"{named.FirstName}, {named.LastName}");
    


    名前のないタプル.各フィールドに名前を付けず、item1 item 2 を使用してタプル内のフィールドを呼び出す一般的な方法を利用します.

    // Unamed Tuple 
    var unnamed = ( "one",  "two");
    Console.WriteLine($"{unnamed.Item1}, {unnamed.Item2}");
    


    タプルと同様に、等号演算子を実行できます

    var item1 = (x: 23, y: 40);
    var item2 = (x: 23, y: 40);
    // utilising the equality operator
    Console.WriteLine(item1 == item2);
    


    したがって、基本的には、このオブジェクトと、オブジェクトのデータ モデルとその中のすべてのフィールドを認識し、比較することができます.

    クラスの値の等価性を定義する方法



    クラスまたは構造体を定義するとき、型の値の等価性 (または等価性) のカスタム定義を作成することが理にかなっているのかどうかを判断します.通常、型のオブジェクトをコレクションに追加することが予想される場合、またはそれらの主な目的が一連のフィールドまたはプロパティを格納することである場合、値の等価性を実装します.

    私たちの実装は、同等性の 5 つの保証に従う必要があります (次のルールでは、xy、および z が null ではないことを前提としています).
  • 再帰プロパティ: x.Equals(x)true を返します.
  • 対称プロパティ: x.Equals(y)y.Equals(x) と同じ値を返します.
  • 推移プロパティ: (x.Equals(y) && y.Equals(z))true を返す場合、 x.Equals(z)true を返します.
  • x.Equals(y) を連続して呼び出すと、x と y によって参照されるオブジェクトが変更されない限り、同じ値が返されます.
  • null 以外の値は null と等しくありません.ただし、x.Equals(y) が null の場合、x は例外をスローします. Equals への引数に応じて、ルール 1 または 2 に違反します.

  • class Bus : IEquatable<Bus> {
                public string Name { get; private set; } // init
                public string Color { get; private set; } // init
    
                public Bus(string name, string color)
                {
                    if(string.IsNullOrEmpty(name))
                    {
                        throw new ArgumentException("Bus must have a name");
                    }
    
                    Name = name;
                    Color = color;
                }
    
                public override bool Equals(object obj) => this.Equals(obj as Bus);
    
                public bool Equals(Bus b)
                {
                    if(b is null)
                    {
                        return false;  
                    }
    
                    if(Object.ReferenceEquals(this, b))
                    {
                        return true;
                    }
    
                    if(this.GetType() != b.GetType())
                    {
                        return false;
                    }
    
                    return (Name == b.Name) && (Color == b.Color);
                }
    
                public static bool operator == (Bus b1, Bus b2)
                {
                    if(b1 is null)
                    {
                        if(b2 is null)
                        {
                            return true;
                        }
    
                        return false;
                    }
    
                    return b1.Equals(b2);
                }
    
                public static bool operator !=(Bus b1, Bus b2) => !(b1 == b2);
            }
    



    var busA = new Bus("School Bus", "Yellow");
    var busB = new Bus("School Bus", "Yellow");
    var busC = new Bus("Public Transport", "Red");
    Bus busD = null;
    
    Console.WriteLine($"busA.Equals(busB): {busA.Equals(busB)}");
    Console.WriteLine($"busA == busB : {busA == busB}");
    Console.WriteLine($"busA.Equals(busD) {busA.Equals(busD)}");
    Console.WriteLine($"busA.Equals(busC): {busA.Equals(busC)}");
    Console.WriteLine($"busA == busC : {busA == busC}");