The “Eight” has not even released RTM, and I am already writing a post about it. What for? Well, the basic idea is that the one who is warned is armed. So in this post it will be about what is known at the moment, and if this is all a setup, well, rightly so.
, , «» . — , NULLnullptrnull
C# , :
public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string MiddleName { get; set; }
  public Person(string first, string last, string middle) =>
    (FirstName, LastName, MiddleName) = (first, last, middle);
  public string FullName =>
    $"{FirstName} {MiddleName[0]} {LastName}";
}
. , , . C# null$string.Format()null
, .. nullOptional
- , . (NuGet JetBrains.Annotations
public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  [CanBeNull] public string MiddleName { get; set; }
  public Person(string first, string last, [CanBeNull] string middle) =>
    (FirstName, LastName, MiddleName) = (first, last, middle);
  public string FullName =>
    $"{FirstName} {MiddleName[0]} {LastName}";
}
NRE MiddleName[0]

Microsoft… , . , VS . . .
, . , . , C#8 :
#nullable enable
. , -
var p = new Person("Dmitri", "Nesteruk", null);
1>NullableReferenceTypes.cs(26,48,26,52): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
-, , ( treat warnings as errors ).
, ? - - C#, MiddleNamenull[0]
:
public string? MiddleName;
, ? - string?Nullable<T>T : structstring
. - , :
public string FullName =>  $"{FirstName} {MiddleName?[0]} {LastName}";
: IL? — ! : nullable nullable [Nullable]
C#8 - -. , nullable-
string? s = GetString();
warning. :
if (s != null){  char c = s[0];}
! , . .
null. — «», , null- .
— . :
(null as Person).FullName
(null as Person)!.FullName
(null as Person)!!!!!!!!!!!!!.FullName
(null as Person)!?.FullNamenull?!
, - BCL .
Type t = Type.GetType("abracadabra");Console.WriteLine(t.Name);
. - Type.GetType()nullnullable
, «»
Type t = Type.GetType("abracadabra");
Type? u = t;
Console.WriteLine(u.Name);
. , t != nullunull
Nullable reference types — , . . , , - nullability , , .
: , , , . , X~N(0,1), E[X²] V[X²]?
, , « ».
, : IndexRange
, intuintx[-1]
. .. -1 , , .
C# . , . , Index
Index i0 = 2; // implicit conversion
, , .
Index
Value
IsFromEnd
:
Index i1 = new Index(0, false);
, , . ( , ) :
var i2 = ^0; // Index(0, true)
! , ^
, , (operator this[]Index
var items = new[] { 1, 2, 3, 4, 5 };
items[^2] = 33; // 1, 2, 33, 4, 5
— Range
X..Y
« X Y». , YY
, :
var a = i1..i2; // Range(i1, i2)
var b = i1..; // Range(i1, new Index(0, true));i1
var c = ..i2; // Range(new Index(0, false), i2)i2
var e = ..;
Range.ToEnd(2);
, ++ (undefined behavior?). , Range
x = {1, 2, 3}x[0..2]{1, 2}x[..2]x[..]{1, 2, 3}
.. x[2]x[^1]Range
-, X..YX <= YArgumentOutOfRangeException
-, «» , 1..2..100
Range
, ,
Substring()
AsSpan()Range
SpanRangeSpan.Slice()
, Index/Rangeoperator this[]
, struct
, :

, . , — ?
. Enumerable.Count()while (x.MoveNext())Count()
if (x is IList<T> list)
  return list.Count;
? IReadOnlyList<T>
, , open-closed principle SOLID, .. — .
? , , , - Count()IReadOnlyList<T>IReadOnlyList<T>.Count()IEnumerable<T>.Count()
. , - -, .
:
public interface IHuman
{
  string Name { get; set; }
    
  public void SayHello() 
  {
    Console.WriteLine($"Hello, I am {Name}");
  }
}
public class Human : IHuman
{
  public string Name { get;set; }
}
, , :
Human human = new Human() { Name = "John" };
human.SayHello(); // will not compile
? , . — , , , .
, ? , , , . HumanSayHello()
: , :
IHuman human = new Human() { Name = "John" };
human.SayHello();
((IHuman)new Human { … }).SayHello();
, , : Foo()Foo()
public interface IHuman
{
  string Name { get; set; }
  
  void SayHello() 
  {
    Console.WriteLine($"Hello, I am {Name}");
  }
}
public interface IFriendlyHuman : IHuman
{
  void SayHello()
  {
    Console.WriteLine(      $"Greeting, my name is {Name}");
  }
}
((IHuman)new Human()).SayHello();
// Hello, I am John
((IFriendlyHuman)new Human()).SayHello();
// Greeting, my name is John
, IFriendlyHuman.SayHello()IHuman.SayHello()SayHello()
public interface IFriendlyHuman : IHuman
{
  void IHuman.SayHello()
  //   ↑↑↑↑↑↑
  {
    Console.WriteLine(      $"Greeting, my name is {Name}");
  }
}
SayHello()IHumanIFriendlyHuman
((IHuman)new Human()).SayHello();
Greeting, my name is John
((IFriendlyHuman)new Human()).SayHello();
Greeting, my name is John
, « override-» - , :
interface ITalk { void Greet(); }
interface IAmBritish : ITalk
{
  void ITalk.Greet() => WriteLine("Good day!");
}
interface IAmAmerican : ITalk
{
  void ITalk.Greet() => WriteLine("Howdy!");
}
class DualNational : IAmBritish, IAmAmerican {}
// Error CS8705 Interface member 'ITalk.Greet()' does not have a most specific implementation. Neither 'IAmBritish.ITalk.Greet()', nor 'IAmAmerican.ITalk.Greet()' are most specific.
, « » ( , ) , , - - IAmAmerican.Greet()
. , , , API. — -. -?
F# . — F# , , # , .
, F# matchswitch
, :
struct PhoneNumber{
  public int Code, Number;
}
var phoneNumber = new PhoneNumber();
var origin = phoneNumber switch {
  { Number: 112 } => "Emergency",
  { Code: 44 } => "UK"
};
phoneNumber
, — , . : default-init ( , default(T)

:

, , :
var origin = phoneNumber switch {
  { Number: 112 } => "Emergency",
  { Code: 44 } => "UK",
  { } => "Indeterminate",
  _ => "Missing"
};
? , 2 : _{}null
, . ?
var origin = phoneNumber switch {
  { Number: 112 } => "Emergency",
  { Code: 44 } => "UK",
  { } => "Unknown"
};
? phoneNumberstructclassnull
, .
- , . nullable reference types — , nullable , recursive patterns — .
F#, , . C# , , , C# — .
, « » C# -, :
var personsOrigin = person switch {
  { Name: "Dmitri" } => "Russia",
  { PhoneNumber: { Code: 46 } } => "Sweden",
  { Name: var name } => $"No idea where {name} lives"
};
. — , person.PhoneNumberCode46
: switch
var error = person switch {
  null => "Object missing",
  { PhoneNumber: null } => "Phone number missing entirely",
  { PhoneNumber: { Number: 0 } } => "Actual number missing",
  { PhoneNumber: { Code: var code } } when code < 0 => "WTF?",
  { } => null // no error
};
if (error != null)
  throw new ArgumentException(error);
, : , when
- «» . , :
IEnumerable<int> GetMainOfficeNumbers()
{
  foreach (var pn in numbers)
  {
    if (pn is ExtendedPhoneNumber { Office: "main" })
      yield return pn.Number;
  }
}
, , . .
— , , . Deconstruct()out
, - :
var type = shape switch
{
  Rectangle((0, 0), 0, 0) => "Point at origin",
  Circle((0, 0), _) => "Circle at origin",
  Rectangle(_, var w, var h) when w == h => "Square",
  Rectangle((var x, var y), var w, var h) =>
    $"A {w}×{h} rectangle at ({x},{y})",
  _ => "something else"
};
, : -, , . «» — , . (_
, . .
, ? , , -. . . , VS 2019 Preview (-, preview RTM), .NET Core 3 ( .NET Framework), dotPeek , .
. () . ■
Source: https://habr.com/ru/post/454446/
All Articles