CSharp 7.0 (C# 7.0)
Eintrag zuletzt aktualisiert am: 24.02.2022
C# 7.0 ist der Nachfolger von
C# 6.0
C# 7.0 ist Verfügbarkeit in
Visual Studio 2017.
Vereinfachte Syntax für out-Variablen
p.GetCoordinates(out var x, out var y);
p.GetCoordinates(out int x, out *); // I only care about x
Pattern matching
if (o is null) return; // constant pattern "null"
if (!(o is int i)) return; // type pattern "int i"
WriteLine(new string('*', i));
Switch statements with patterns
switch(shape)
{
case Circle c:
WriteLine($"circle with radius {c.Radius}");
break;
case Rectangle s when (s.Length == s.Height):
WriteLine($"{s.Length} x {s.Height} square");
break;
case Rectangle r:
WriteLine($"{r.Length} x {r.Height} rectangle");
break;
default:
WriteLine("<unknown shape>");
break;
case null:
throw new ArgumentNull
Exception(nameof(shape));
}
Tuples für multiple Rückgabewerte
(string, string, string) LookupName(long id) // tuple return type
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
var names = LookupName(id);
WriteLine($"found {names.Item1} {names.Item3}.");
(string first, string middle, string last) LookupName(long id) // tuple elements have names
{
... // retrieve first, middle and last from data storage
return (first, middle, last); // tuple literal
}
var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");
(string, string, string) LookupName(long id) // tuple elements have names
{
... // retrieve first, middle and last from data storage
return (first: first, middle: middle, last: last); // named tuple elements in a literal
}
var names = LookupName(id);
WriteLine($"found {names.first} {names.last}.");
Deconstruction für Tupel
(var first, var middle, var last) = LookupName(id1); // var inside
var (first, middle, last) = LookupName(id1); // var outside
(first, middle, last) = LookupName(id2); // deconstructing assignment
Deconstruction für andere Typen
public void Deconstruct(out T1 x1, ..., out Tn xn) { ... }
Lokale Funktionen
public int Fibonacci(int x)
{
if (x < 0) throw new Argument
Exception("Less negativity please!", nameof(x));
return Fib(x).current;
(int current, int previous) Fib(int i)
{
if (i == 0) return (1, 0);
var (p, pp) = Fib(i - 1);
return (p + pp, p);
}
}
public
IEnumerable<T> Filter<T>(
IEnumerable<T> source, Func<T, bool> filter)
{
if (source == null) throw new ArgumentNull
Exception(nameof(source));
if (filter == null) throw new ArgumentNull
Exception(nameof(filter));
return
Iterator();
IEnumerable<T>
Iterator()
{
foreach (var element in source)
{
if (filter(element)) { yield return element; }
}
}
}
Trennstriche in Literalen
Unterstriche haben keine Auswirkung auf den Wert, dienen nur der Übersichtlichkeit
var d = 123_456;
var x = 0xAB
CDEF;
var b = 0b1010
1011_1100_1101_11101111;
Ref returns and locals
public ref int Find(int number, int[] numbers)
{
for (int i = 0; i < numbers.Length; i++)
{
if (numbers[i] == number)
{
return ref numbers[i]; // return the storage location, not the value
}
}
throw new IndexOutOfRange
Exception($"{nameof(number)} not found");
}
int[] array = { 1, 15, -39, 0, 7, 14, -12 };
ref int place = ref Find(7, array); // aliases 7's place in the array
place = 9; // replaces 7 with 9 in the array
WriteLine(array[4]); // prints 9
Generalized async return types (mit System.Threading.Tasks.Extensions)
public async ValueTask<int> Func()
{
await Task.Delay(100);
return 5;
}
Expression bodied members auch in Konstruktor und Destruktor/Finalizer
public Person(string name) => names.TryAdd(id, name); // constructors
~Person() => names.TryRemove(id, out *); // destructors
Throw in mehr Situationen möglich
public Person(string name) => Name = name ?? throw new ArgumentNull
Exception(name);
public string GetLastName() => throw new NotImplemented
Exception();