C#7の新しいout変数機能について読んでいました here 。 2つの質問があります。
それは言います
_
の形式で「破棄」することもできます。これは、気にしないアウトパラメーターを無視できるようにするためです。p.GetCoordinates(out var x, out _); // I only care about x
Q:これは単なる情報であり、C#7の新しい機能ではないようです。
var _;
if (Int.TryParse(str, out _))
...
または私はここで何かが欠けていますか?
同じブログで言及されているようにコードを実行するとエラーが発生します。
~Person() => names.TryRemove(id, out *);
*
は有効な識別子ではありません。 Mads Torgersenによる監視だと思いますか?
Discards 、C#7では、変数が宣言されている場所であればどこでも使用できます。名前が示すとおり、結果を破棄します。したがって、廃棄はout変数で使用できます。
p.GetCoordinates(out var x, out _);
また、式の結果を破棄するために使用できます。
_ = 42;
例では、
p.GetCoordinates(out var x, out _);
_ = 42;
導入される変数_
はありません。使用されている廃棄のケースは2つだけです。
ただし、スコープに識別子_
が存在する場合、破棄は使用できません。
var _ = 42;
_ = "hello"; // error - a string cannot explicitly convert from string to int
これの例外は、_
変数がout変数として使用される場合です。この場合、コンパイラーは型またはvar
を無視し、破棄として扱います。
if (p.GetCoordinates(out double x, out double _))
{
_ = "hello"; // works fine.
Console.WriteLine(_); // error: _ doesn't exist in this context.
}
これは、この場合、out var _
またはout double _
が使用されている場合にのみ発生することに注意してください。 out _
を使用するだけで、スコープ内にある場合は、既存の変数_
への参照として扱われます。例:
string _;
int.TryParse("1", out _); // complains _ is of the wrong type
最後に、*
表記法は破棄に関する議論の初期に提案されました しかし、他の言語でより一般的に使用される表記法であるため、_
を支持して放棄されました 。
C#7の破棄演算子_
の別の例は、C#7で最近追加されたobject
ステートメントのswitch
型の変数 パターンマッチ :
コード:
static void Main(string[] args)
{
object x = 6.4;
switch (x)
{
case string _:
Console.WriteLine("it is string");
break;
case double _:
Console.WriteLine("it is double");
break;
case int _:
Console.WriteLine("it is int");
break;
default:
Console.WriteLine("it is Unknown type");
break;
}
// end of main method
}
このコードはタイプと一致し、case ... _
に渡された変数を破棄します。
次のスニペットを検討してください
static void Main(string[] args)
{
//....
int a;
int b;
Test(out a, out b);
Test(out _, out _);
//....
}
private static void Test(out int a, out int b)
{
//...
}
これが何が起こっているかです:
...
13: int a;
14: int b;
15:
16: Test(out a, out b);
02340473 lea ecx,[ebp-40h]
02340476 lea edx,[ebp-44h]
02340479 call 02340040
0234047E nop
17: Test(out _, out _);
0234047F lea ecx,[ebp-48h]
02340482 lea edx,[ebp-4Ch]
02340485 call 02340040
0234048A nop
...
背後でわかるように、2つの呼び出しは同じことをしています。
@ServéLaurijssenが指摘したように、クールなことはpre-declare変数を必要としないことです。これは、値に興味がない場合に便利です。
最初の質問について
これは単なる情報であり、C#7の新機能ではないと思います。C#7.0以前でも同様のことができるからです。
var _; if (Int.TryParse(str, out _)) // ...
斬新な点は、式の内側または外側で_
を宣言する必要がなくなり、入力するだけで済むことです。
int.TryParse(s, out _);
C#7の前にこの1つのライナーを試してください:
private void btnDialogOk_Click_1(object sender, RoutedEventArgs e)
{
DialogResult = int.TryParse(Answer, out _);
}