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