
Alle zuvor in den Nebenversionen von C # eingefĂŒhrten Tools sind so konzipiert, dass sie die Sprache nicht wesentlich Ă€ndern. Sie Ă€hneln eher Syntaxverbesserungen und kleinen ErgĂ€nzungen der neuen Funktionen von C # 7.0 .
Dieser Ansatz war bewusst und bleibt gĂŒltig.
Schwerwiegendere Ănderungen, die in allen Entwicklungsphasen (Design, Implementierung und Test) mehr Arbeit erfordern, werden weiterhin nur mit den Hauptsprachenversionen veröffentlicht. Obwohl die endgĂŒltige Nebenversion von C # 7 noch nicht veröffentlicht wurde, arbeitet das Team bereits aktiv an der nĂ€chsten Hauptversion der Sprache: C # 8.0.
In diesem Artikel möchte ich eine Auswahl der derzeit geplanten Funktionen vorstellen, die voraussichtlich in der endgĂŒltigen Version enthalten sein werden. Alle befinden sich in einem frĂŒhen Entwicklungsstadium und können sich Ă€ndern.
Nullable Referenztypen
Dieses Tool wurde bereits in den frĂŒhen Phasen der C # 7.0-Entwicklung angeboten, jedoch bis zur nĂ€chsten Hauptversion verzögert. Ziel ist es, dem Entwickler dabei zu helfen, unbehandelte NullReferenceException zu vermeiden.
Die Hauptidee besteht darin, bei der Bestimmung des Variablentyps anzugeben, ob er null sein kann oder nicht:
IWeapon? canBeNull;
IWeapon cantBeNull;
null , null -null , ( , , ):
canBeNull = null; //
cantBeNull = null; //
cantBeNull = canBeNull; //
, nullable- null:
canBeNull.Repair(); //
cantBeNull.Repair(); //
if (canBeNull != null) {
cantBeNull.Repair(); //
}
, : , null. , null- .
nullability , . , .
Visual Studio 2017 15.6 update.
Records
, - C# , -.
:
public class Sword(int Damage, int Durability);
:
public class Sword : IEquatable<Sword>
{
public int Damage { get; }
public int Durability { get; }
public Sword(int Damage, int Durability)
{
this.Damage = Damage;
this.Durability = Durability;
}
public bool Equals(Sword other)
{
return Equals(Damage, other.Damage)
&& Equals(Durability, other.Durability);
}
public override bool Equals(object other)
{
return (other as Sword)?.Equals(this) == true;
}
public override int GetHashCode()
{
return (Damage.GetHashCode() * 17 + Durability.GetHashCode());
}
public void Deconstruct(out int Damage, out int Durability)
{
Damage = this.Damage;
Durability = this.Durability;
}
public Sword With(int Damage = this.Damage, int Durability
= this.Durability) => new Sword(Damage, Durability);
}
, , . GetHashCode - Dictionary Hashtable. Deconstruct :
var (damage, durability) = sword;
, , , . , , . , , With, :
var strongerSword = sword.With(Damage: 8);
, :
var strongerSword = sword with { Damage = 8 };
Recursive Patterns
C# 7.0. 8.0 :
. Deconstruct():
if (sword is Sword(10, var durability)) {
// , Damage = 10
// durability sword.Durability
}
(tuple) :
switch (state, transition)
{
case (State.Running, Transition.Suspend):
state = State.Suspended;
break;
}
switch , . , :
state = (state, transition) switch {
(State.Running, Transition.Suspend) => State.Suspended,
(State.Suspended, Transition.Resume) => State.Running,
(State.Suspended, Transition.Terminate) => State.NotRunning,
(State.NotRunning, Transition.Activate) => State.Running,
_ => throw new InvalidOperationException()
};
Default Interface Methods
, C# , :
interface ISample
{
void M1(); //
void M2() => Console.WriteLine("ISample.M2"); //
}
, :
abstract class SampleBase
{
public abstract void M1();
public void M2() => Console.WriteLine("SampleBase.M2");
}
, C# 8 , . , .
. , . , . , . , .
C#, .
, . , â trait .
, , . C# 8.0 , :
Asynchronous Streams
C# . C# 8.0, . IEnumerable IEnumerator:
public interface IAsyncEnumerable<out T>
{
IAsyncEnumerator<T> GetAsyncEnumerator();
}
public interface IAsyncEnumerator<out T> : IAsyncDisposable
{
Task<bool> MoveNextAsync();
T Current { get; }
}
, IDisposable:
public interface IAsyncDisposable
{
Task DisposeAsync();
}
:
var enumerator = enumerable.GetAsyncEnumerator();
try
{
while (await enumerator.WaitForNextAsync())
{
while (true)
{
Use(enumerator.Current);
}
}
}
finally
{
await enumerator.DisposeAsync();
}
â , while(true). - , . , , . , , .
, . , foreach. :
foreach await (var item in enumerable)
{
Use(item);
}
, foreach , .
, yield. , :
async IAsyncEnumerable<int> AsyncIterator()
{
try
{
for (int i = 0; i < 100; i++)
{
yield await GetValueAsync(i);
}
}
finally
{
await HandleErrorAsync();
}
}
LINQ.
Ranges
:
var range = 1..5;
, :
struct Range : IEnumerable<int>
{
public Range(int start, int end);
public int Start { get; }
public int End { get; }
public StructRangeEnumerator GetEnumerator();
// overloads for Equals, GetHashCode...
}
:
Span<T> this[Range range]
{
get
{
return ((Span<T>)this).Slice(start: range.Start,
length: range.End - range.Start);
}
}
foreach (var index in min..max)
{
//
}
switch (value)
{
case 1..5:
//
break;
}
step â , . â ( ). Python, .
, , .., . , .
, , , ..:
a[start:end] # start end-1
a[:end] # items end-1
, .
Generic Attributes
. , , :
public class TypedAttribute : Attribute
{
public TypedAttribute(Type type)
{
// ...
}
}
, :
public class TypedAttribute<T> : Attribute
{
public TypedAttribute()
{
// ...
}
}
, , :
public TypedAttribute(T value)
{
// ...
}
Default Literal in Deconstruction
C# 7, :
(int x, int y) = (default, default);
default, :
(int x, int y) = default;
Caller Argument Expression
C# 5, CallerMemberName, CallerFilePath CallerLineNumber) .
CallerMemberName INotifyPropertyChanged:
class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private int property;
public int Property
{
get { return property; }
set
{
if (value != property)
{
property = value;
OnPropertyChanged();
}
}
}
}
C# 8 CallerArgumentExpression, , :
public Validate(int[] array, [CallerArgumentExpression("array")] string arrayExpression = null)
{
if (array == null)
{
throw new ArgumentNullException(nameof(array), $"{arrayExpression} was null.");
}
if (array.Length == 0)
{
throw new ArgumentException($"{arrayExpression} was empty.", nameof(array));
}
}
, , .
Target-typed new Expression
, var ( ) :
Dictionary<string, string> dictionary = new Dictionary<string, string>(); // var
var dictionary = new Dictionary<string, string>(); // var
(), , :
class DictionaryWrapper
{
private Dictionary<string, string> dictionary = new Dictionary<string, string>();
// ...
}
C# 8, new, :
class DictionaryWrapper
{
private Dictionary<string, string> dictionary = new();
// ...
}
, , . , .
Ordering of ref and partial Modifiers on Type Declarations
C# , partial struct class.
ref C# 7.2, partial , , ref struct, partial partial, .
, :
public ref struct NonPartialStruct { }
public ref partial struct PartialStruct { }
C# 8, , :
public partial ref struct PartialStruct { }
C# 8 . .
, C# 8.0, . , , . , , .
, , . .
C# 7.1, 7.2 and 7.3 â New Features (Updated).
, C#. C# â - ? , :
- var . . . , .
- Go . . -. , , ( ) .
- C# . ( .Net Framework 1.1), ( «» LINQ â , SQL, ). , .
- - typedef, , , (var ). new(), ( ).
, , . GO C# . , . C# , â .
? . . C# â Common Language Infrastructure (CLI). CLI , , . Java/Kotlin. , ?
( Nullable Reference Types). , .