O G8 ainda não lançou o RTM ainda, e eu já estou escrevendo um post sobre isso. Porque Bem, a idéia principal é que quem é avisado está armado. Portanto, neste post, será sobre o que é conhecido atualmente, e se é tudo uma configuração, bem, com razão.
Tipos de referência anuláveis
, , «» . — , 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
( — ):
:
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». , Y
— Y
. .
, :
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
:
, 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 , .
. () . â–