C#8有什么新功能?

G8甚至还没有发布RTM,我已经在写有关它的文章。 怎么了 好吧,主要的想法是,被警告的人是武装的。 因此,在本篇文章中,将介绍当前已知的内容,如果全部都是设置,那么正确。



可空引用类型


, , «» . — , NULL nullptr ++. — zero-terminated strings, (n). null.


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-, NRE (NullReferenceException).


, .. null, 100500 . Optional , , .


- , . (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);

warning:

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#, MiddleName null [0] .


:


public string? MiddleName;

, ? - string? Nullable<T>, , T : struct, - . — , .. string.


. - , :


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 warning

  • (null as Person)!.FullName warning , ..

  • (null as Person)!!!!!!!!!!!!!.FullName

  • (null as Person)!?.FullName null; , ?!,



, - BCL .


Type t = Type.GetType("abracadabra");Console.WriteLine(t.Name);

. - Type.GetType() null , BCL nullable , .


, «»


Type t = Type.GetType("abracadabra");
Type? u = t;
Console.WriteLine(u.Name);

. , t != null, u null, .



Nullable reference types — , . . , , - nullability , , .



: , , , . , X~N(0,1), E[X²] V[X²]?


, , « ».


, : Index Range.


Index


, int uint? : ( ). , C# x[-1] .


. .. -1 , , .


C# . , . , Index , :


Index i0 = 2; // implicit conversion

, , .


Index ( — ):


  • Value,

  • IsFromEnd — , ,


:


Index i1 = new Index(0, false);

, , . ( , ) :


var i2 = ^0; // Index(0, true)

! , ^ ( , LaTeX, ), « ».


, , (operator this[]) Index,


var items = new[] { 1, 2, 3, 4, 5 };
items[^2] = 33; // 1, 2, 33, 4, 5

Range


Range, , , 1. :


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); — — , ; , dotPeek, ilSpy


?


, ++ (undefined behavior?). , Range C# . : « ».


x = {1, 2, 3}. x[0..2] {1, 2}, x[..2] x[..], {1, 2, 3}.


.. x[2] x[^1] — , Range- !



-, X..Y X <= Y ( ?). ( 7..3), ArgumentOutOfRangeException. .. , .


-, «» , 1..2..100 . . MATLAB.


Range :


  • , ,

  • Substring(). C# .

  • AsSpan() Range.

  • Span RangeSpan.Slice(), -.


, Index/Range operator this[]. , « » . , (singly linked list), - « » — .



, struct-. - , «» , .


, :




Default Interface Members


, . , — ?


. 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

? , . — , , , .


, ? , , , . Human SayHello()? , .


: , :


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() override- IHuman.SayHello(), ! SayHello() ? :


public interface IFriendlyHuman : IHuman
{
  void IHuman.SayHello()
  //   ↑↑↑↑↑↑
  {
    Console.WriteLine(      $"Greeting, my name is {Name}");
  }
}

SayHello() , IHuman IFriendlyHuman , :


((IHuman)new Human()).SayHello();
Greeting, my name is John
((IFriendlyHuman)new Human()).SayHello();
Greeting, my name is John

Diamond Inheritance


, « 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. — -. -?


Pattern Matching


F# . — F# , , # , .


, F# match # switch. C#8 .


Property Matching


, :


struct PhoneNumber{
  public int Code, Number;
}
var phoneNumber = new PhoneNumber();
var origin = phoneNumber switch {
  { Number: 112 } => "Emergency",
  { Code: 44 } => "UK"
};

phoneNumber, . switch statement switch expression, - .


, — , . : 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"
};

? phoneNumber struct — , class. - , null, … nullable reference types!


, .



- , . 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.PhoneNumber Code 46. — . , «».



: 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/zh-CN454446/


All Articles