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. :






All Articles