C#7の予期しない動作を修正するか、そのままにしておくと、言語の構文が複雑になり補償されますか?

C#には長い間「is」ステートメントがあり、その目的はかなり明確です。

if (p is Point) Console.WriteLine("p is Point");
else Console.WriteLine("p is not Point or null");

null

if (p is object) Console.WriteLine("p is not null");
if (p is null) Console.WriteLine("p is null");

C# 7 pattern-matching

if (GetPoint() is Point p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");

if (GetPoint() is var p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");

, , 'null'? ?

, , , ( JetBrains !) , 'GetPoint() is var p' , 'GetPoint() is AnyType p' .

'var' , , [type inference].

C# 7 , , 'var', - …

, , , , , , , , . , , , , , .

? .

public static class LanguageExtensions
{
    public static bool IsNull(this object o) => o is null;
    public static bool Is<T>(this object o) => o is T;
    public static bool Is<T>(this T o) => o != null; /* or same 'o is T' */
    public static bool Is<T>(this T o, out T x) => (x = o) != null; /* or same '(x = o) is T' */
    /* .... */

    public static T As<T>(this object o) where T : class => o as T;
    public static T Of<T>(this object o) => (T) o;
}

public Point GetPoint() => null; // new Point { X = 123, Y = 321 };

if (GetPoint().Is(out AnyType p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");

if (GetPoint().Is(out var p) Console.WriteLine("o is Any Type");
else Console.WriteLine("It is not Point.");

, - .

, , !

if (GetPoint() is AnyType p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");

if (GetPoint() is {} p) Console.WriteLine("o is Any Type");
else Console.WriteLine("It is not Point.");

if (GetPoint() is var p) Console.WriteLine("Always true");

, , pattern-matching.



if (GetPoint() is AnyType p { X is int x, Y is int y}) Console.WriteLine($"X={x} Y={y}");
else Console.WriteLine("It is not Point.");

if (GetPoint() is var p { X is int x, Y is int y}) Console.WriteLine($"X={x} Y={y}");
else Console.WriteLine("It is not Point.");

if (GetPoint() is { X is int x, Y is int y}) Console.WriteLine($"X={x} Y={y}");
else Console.WriteLine("It is not Point.");

( )

if (GetPoint() is AnyType { X is int x, Y is int y} p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");

if (GetPoint() is var { X is int x, Y is int y} p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");
// but
if (GetPoint() is var p) Console.WriteLine($"Always true");

if (GetPoint() is { X is int x, Y is int y} p) Console.WriteLine($"X={p.X} Y={p.Y}");
else Console.WriteLine("It is not Point.");

, -, «» '{ }'.

— 'x is var y' , breaking change, .

, , , breaking change, .

, C# 8 Null Reference Types. ,

public bool SureThatAlwaysTrue(AnyType item) => item is var x;

C# 8, , 'false', 'item == null', , C# 8 'AnyType item' , 'item != null' ( 'SureThatAlwaysTrue(null)' warning message 'SureThatAlwaysTrue(null)'). '!' 'SureThatAlwaysTrue(null!)'

public bool SureThatAlwaysTrue(AnyType? item) => item is var x;

breaking change Nullable Value Types, C# 7

public bool SureThatAlwaysTrue(int? item) => item is var x;

warning message [breaking change].

, , : breaking change ?

, , «» «». .

:
Question: what does 'var' mean?

«» «» :
Pattern-matching rethinking (at C# 8 Nullable Reference Types context)

P.S. :



Source: https://habr.com/ru/post/J345102/


All Articles