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.
, , «» . — , NULL
nullptr
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
, .. null
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);
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
(null as Person)!.FullName
(null as Person)!!!!!!!!!!!!!.FullName
(null as Person)!?.FullName
null
?!
, - BCL .
Type t = Type.GetType("abracadabra");Console.WriteLine(t.Name);
. - Type.GetType()
null
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
, int
uint
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)
! , ^
, , (operator this[]
Index
var items = new[] { 1, 2, 3, 4, 5 };
items[^2] = 33; // 1, 2, 33, 4, 5
— Range
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);
, ++ (undefined behavior?). , Range
x = {1, 2, 3}
x[0..2]
{1, 2}
x[..2]
x[..]
{1, 2, 3}
.. x[2]
x[^1]
Range
-, X..Y
X <= Y
ArgumentOutOfRangeException
-, «» , 1..2..100
Range
, ,
Substring()
AsSpan()
Range
Span
Range
Span.Slice()
, Index/Range
operator 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
? , . — , , , .
, ? , , , . 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()
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
, « 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# match
switch
, :
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"
};
? phoneNumber
struct
class
null
, .
- , . 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/454446/
All Articles