新しいC#7.2。 スパンおよびメモリ





こんにちは、%habrauser%! スタックに保存された変数を使用して転送するときにシステムの速度が低下するという問題に直面して、Googleにアクセスし、C#7.2言語バージョンで追加されたSpan <T>コレクションを使用した優れたソリューションを見つけました。 しかし、RuNetにはこの更新に関する記事はほとんどないことに気付きました。 したがって、私は初心者に役立つかもしれない短い記事をスケッチすることにしました。



新しいプライベート保護アクセス修飾子が追加されました



このアクセス修飾子は、同じアセンブリ内の派生クラスのみを呼び出す機能を提供します。 以前に実装された保護内部修飾子とは対照的に、派生クラスと同じアセンブリのすべてのクラスの両方にアクセスできました。



劣った名前付き引数



C#は、いわゆる名前付き引数を使用できます。 パラメータ名を手動で指定した場合、開発者はメソッドパラメータの必要な順序を覚えておくことができません。 このメソッドのシグネチャを見てみましょう。



public void Print(string text, int size, string title)
      
      





通常どおりこのメソッドを呼び出すことができます



 Print("Hello, World!", 24, "Hi!");
      
      





また、名前付き引数を使用して、パラメーターをランダムな順序で設定できます。 または、引数の一部を順番に設定し(このような引数は定位置と呼ばれます)、名前を使用して残りを設定します。



 Print(size: 24, title: "Hi!", text: "Hello, World!"); Print("Hello, World!", title: "Hi!", size: 24);
      
      





そのため、他の名前付き引数のみが名前付き引数の後に行くことができるという制限がありました。 名前付き引数の後に位置引数が指定された場合、エラーメッセージが発行されました。 これで、引数が名前付き引数の後の正しい位置にある場合、プログラムは正しく動作します。



 Print(text: "Hello, World!", 24, "Hi!");
      
      





ただし、同時に、位置の順序に違反している場合は、エラーメッセージが表示されます。 サイズが適切であるにもかかわらず、タイトルとテキストが入れ替わっているため、指定されたコードは機能しません。



 Print(title: "Hi!", 24, text: "Hello, World!"); // .
      
      





数値リテラルの最初の下線



C#言語は、「_」アンダースコア区切り文字を使用してバイナリおよび16進リテラルを使用する機能をすでに実装しているため、リテラルの最初の文字としての使用は以前は禁止されていました。 現在、この制限は削除されています。



 int i = 0b1101_0111; //     . int i = 0b_1101_0111; //    .
      
      





値で保存されたデータ型の参照を使用する



まず、2種類のデータがあることを思い出してください。





さらに、重要な型がメソッドに渡された場合、新しいコピーが作成されるため、アクセス修飾子(ref)が使用されない場合、メソッド内の元の変数を変更することはできませんでした。 しかし、参照型がメソッドに渡された場合、オブジェクトのコピーは実行されず、メソッドでオブジェクトを変更すると元のオブジェクトが変更されました。



重要な型がメソッドに転送されると、毎回新しいコピーが作成され、システムのスローダウンとメモリの過剰使用が発生するため、ここでは明らかな問題はありません。 これは、スタックに格納されているバルク構造の場合に特に当てはまります。 引数として20個のフィールドを持つ構造体を渡す再帰的なメソッド呼び出しを想像してください。したがって、新しいバージョンの言語では、値で保存された変数の処理を最適化するための手順がとられています。



in修飾子が追加されました。これは、重要な型を参照で渡す必要があることを示していますが、メソッド内で変更できないという制限があります。



 private int Sum(in int value1, in int value2);
      
      





構造体構造もスタックに格納されるため、読み取り専用修飾子が追加されます。これは、本質的にin



 readonly public struct ReadonlyPosition { public ReadonlyPosition(int x, int y) { X = x; Y = y; } public int X { get; } public int Y { get; } private static readonly ReadonlyPosition _position = new ReadonlyPosition(); public static ref ReadonlyPosition Position => ref _position; }
      
      





ref struct修飾子が追加されました。これは、構造体が参照によって渡され、スタックの割り当てで処理される必要があることを示します。



また、参照によって値が返されることを示すアクセス修飾子ref readonlyが追加されましたが、対応する変数を変更することは禁止されています。



最後に、Span <T>タイプが追加されました。これにより、スタックに格納されているが参照によってアクセスされるデータのコレクションを作成できます。 Type Memory <T>は、Span <T>型の拡張であり、スタックに格納されているコレクションへの参照によるスレッドセーフアクセスに使用されます。



これで、更新プログラムの短いレビューは終わりです。 この情報が誰かに役立つことを願っています。 私は、言語の変化と革新を最も簡単な言語で記述しようとしました。 お時間をいただきありがとうございます。



出典: C#7.2の新機能| マイクロソフトドキュメント



All Articles