C#7は多くの新機能を追加し、データ消費、コードの簡素化、パフォーマンスに焦点を当てています。 最大の機能はすでに考慮されています-
タプル 、
ローカル関数 、
パターンマッチング、および
式を
投げます 。 しかし、大小を問わず他の新しい機会があります。 これらはすべて組み合わされてコードがより効率的で理解しやすくなり、誰もが幸せで生産的になります。
C#の新しいバージョンの他の機能を見てみましょう。 だから! さあ始めましょう!
アウト変数
現在、C#では、
outパラメーターの使用は 、私たちが望むほど柔軟で
はありません。
outパラメータを使用し
てメソッドを呼び出す前に、まずメソッドに渡す変数を宣言する必要があります。 通常、これらの変数は初期化されないため(メソッドによって書き換えられるため)、
varを使用して変数を宣言することはできません。したがって、完全な型を指定する必要があります。
public void PrintCoordinates(Point p) { int x, y;
C#7では、
out変数が導入されています。 これらを使用すると、変数を
out引数として渡す場所で変数を宣言できます。
public void PrintCoordinates(Point p) { p.GetCoordinates(out int x, out int y); WriteLine($"({x}, {y})"); }
変数は閉じているブロックの外側のスコープに移動するため、次の行で使用できることに注意してください。out変数は
outパラメーターの引数として直接宣言されているため、コンパイラーは(競合するオーバーロードがない場合)型を推測できるため、宣言時に型の代わりに
varを使用できます。
p.GetCoordinates(out var x, out var y);
通常、
出力パラメータは
Try ...テンプレートで使用され、論理的な戻り値は成功を示し、
出力パラメータは結果を保持します。
public void PrintStars(string s) { if (int.TryParse(s, out var i)) { WriteLine(new string('*', i)); } else { WriteLine("Cloudy - no stars tonight!"); } }
_の形式の
出力パラメーターで「
ワイルドカード 」を使用して、不要な
出力パラメーターを無視
することもできます。
p.GetCoordinates(out int x, out _);
ワイルドカードを使用して型宣言を省略することができることに注意してください。
string inputDate = ""; if (DateTime.TryParse(inputDate, out DateTime dt)) {
問題は、文字列を
DateTime型の変数に変換できなかった場合、出力値を使用しようとする場合です。
変数に
はデフォルト値があります 。
リテラルの機能強化
C#7では、数値リテラル内の数字の区切り文字として「
_ 」文字を使用できます。
var d = 123_456; var x = 0xAB_CD_EF;
この文字は、読みやすさを向上させるために、必要な回数だけ数字の間のどこにでも配置できます。 値には影響しません。
区切り文字は、
byte 、
int 、
long 、
decimal 、
float 、および
double型とともに使用できます。
public const long BillionsAndBillions = 100_000_000_000; public const double AvogadroConstant = 6.022_140_857_747_474e23; public const decimal GoldenRatio = 1.618_033_988_749_894_848_204_586_834_365_638_117_720_309_179M;
さらに、C#7は
バイナリリテラルを提供し
ます 。 これで、バイナリ形式で数値を書くことができます。
var b = 0b101010111100110111101111;
定数の先頭の
0bは、数値がバイナリ形式で書き込まれることを意味します。
小数点区切り文字を使用することもできます。これにより、リテラルの可読性が確実に向上します。
var b = 0b1010_1011_1100_1101_1110_1111;
放電区切り文字は、リテラルの末尾または先頭に立つことはできません
byte a = 0b_0000_0001;
Refの戻り値とローカル
(
ref修飾子を使用して)参照によってメソッドパラメーターを渡すことができるように、参照によってそれらを返すことも、ローカル変数に参照によって保存することもできるようになりました。
public ref int Find(int number, int[] numbers) { for (int i = 0; i < numbers.Length; i++) { if (numbers[i] == number) { return ref numbers[i];
これは、大きなデータ構造から特定のフィールドを返す場合に便利です。 たとえば、ゲームには、事前に分散された構造の大きな配列にデータが含まれている場合があります(ガベージコレクションの一時停止を避けるため)。 現在、メソッドは、呼び出し元のメソッドが読み取りおよび変更できる構造体へのリンクを直接返すことができます。
いくつかのセキュリティ制限があります。
- あなたは「安全に返す」リンクのみを返すことができます:あなたに渡されたリンクとオブジェクトのフィールドを指すリンクのみ
- ローカルref変数は特定の保存場所で初期化され、別の場所を指すように変更することはできません
非同期メソッドで返されるジェネリック型
これまでのところ、C#の
非同期メソッドは
void 、
Task、または
Task ‹T›を返す必要があります。 C#7では、非同期メソッドから返されるように他の型を定義できます。 戻り値の型は非同期パターンと一致する必要があります。つまり、
GetAwaiterメソッドが使用可能でなければなりません。 ケーススタディ:.NET Frameworkは、この新しい言語機能を使用する新しい
ValueTask型を追加します
Taskおよび
Task ‹T›は参照型であるため、パフォーマンスに影響するセグメントにメモリを割り当てると(特に限られたサイクルでメモリを割り当てる場合)、パフォーマンスが大幅に低下する可能性があります。 汎用戻り型のサポートにより、参照型の代わりに意味のある小さな型を返すことができます。これにより、メモリの過剰割り当てを防ぐことができます。
class Program { static Random rnd; static void Main() { Console.WriteLine($"You rolled {GetDiceRoll().Result}"); } private static async ValueTask GetDiceRoll() { Console.WriteLine("...Shaking the dice..."); int roll1 = await Roll(); int roll2 = await Roll(); return roll1 + roll2; } private static async ValueTask Roll() { if (rnd == null) rnd = new Random(); await Task.Delay(500); int diceRoll = rnd.Next(1, 7); return diceRoll; } }
おわりに
開発を容易にし、時間を節約し、コードを読みやすくするため、C#言語の新機能を使用します。 この記事では、C#7バージョンに関する一連の記事を終了します。 興味のある質問は、コメントまたはPMでお願いします。 答えます。 みんなありがとう!