[ad_1]
For all .NET developers who are still working with the classic .NET Framework 4.8 (or even older versions), sadly there is a sad message ahead: C # 9.0 can no longer be used there. C # 9.0 only runs on .NET 5.0 and .NET Core 3.0 / 3.1, as well as on Xamarin.
Concise types with records
The absolute highlight in C # are records, with which you can concisely define classes with value semantics. The following line of code that looks like a constructor preceded by a keyword record
, declares a class Person
with three properties ID
, Vorname
, Name
is Status
(The latter with default value):
public record Person(int ID, string Vorname, string Name, string Status = "unbekannt");
This record class can now be instantiated as a normal class:
Person hs = new Person(123, "Holger", "Schwichtenberg");
and use the data contained therein through the automatically generated properties:
Console.WriteLine($"Person #{hs.ID}: {hs.Vorname} {hs.Name}");
You’ll immediately notice a difference with a normal class if you try to change the value of a property. This assignment after the instance
hs.Vorname = "Dr. Holger";
the compiler no longer allows it and recognizes it with the error
"Error CS8852 Init - only property or indexer 'Person.Vorname' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor".
Instances of a record class defined in this way are immutable after being instantiated. The new key word record
it’s a lot of syntactic sugar. With a free decompiler like ILSpy you can reveal that more than one A4 page of program code has actually been created (see Listing 1).
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
public class Person : IEquatable<Person>
{
protected virtual Type EqualityContract
{
[System.Runtime.CompilerServices.NullableContext(1)]
[CompilerGenerated]
get
{
return typeof(Person);
}
}
public int ID { get; init; }
public string Vorname { get; init; }
public string Name { get; init; }
public string Status { get; init; }
public Person(int ID, string Vorname, string Name, string Status = "unbekannt")
{
this.ID = ID;
this.Vorname = Vorname;
this.Name = Name;
this.Status = Status;
base..ctor();
}
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("Person");
stringBuilder.Append(" { ");
if (PrintMembers(stringBuilder))
{
stringBuilder.Append(" ");
}
stringBuilder.Append("}");
return stringBuilder.ToString();
}
protected virtual bool PrintMembers(StringBuilder builder)
{
builder.Append("ID");
builder.Append(" = ");
builder.Append(ID.ToString());
builder.Append(", ");
builder.Append("Vorname");
builder.Append(" = ");
builder.Append((object?)Vorname);
…
return true;
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static bool operator !=(Person? r1, Person? r2)
{
return !(r1 == r2);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static bool operator ==(Person? r1, Person? r2)
{
return (object)r1 == r2 || (r1?.Equals(r2) ?? false);
}
public override int GetHashCode()
{
return (((EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<int>.Default.GetHashCode(ID)) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Vorname)) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Name)) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Status);
}
public override bool Equals(object? obj)
{
return Equals(obj as Person);
}
public virtual bool Equals(Person? other)
{
return (object)other != null && EqualityContract == other!.EqualityContract && EqualityComparer<int>.Default.Equals(ID, other!.ID) && EqualityComparer<string>.Default.Equals(Vorname, other!.Vorname) && EqualityComparer<string>.Default.Equals(Name, other!.Name) && EqualityComparer<string>.Default.Equals(Status, other!.Status);
}
public virtual Person <Clone>$()
{
return new Person(this);
}
protected Person(Person original)
{
ID = original.ID;
Vorname = original.Vorname;
Name = original.Name;
Status = original.Status;
}
public void Deconstruct(out int ID, out string Vorname, out string Name, out string Status)
{
ID = this.ID;
Vorname = this.Vorname;
Name = this.Name;
Status = this.Status;
}
}
Listing 1: Decompilation of the “Person” record type with the ILSpy decompiler
betterCode () presents: .NET 5.0 – The online event on December 3, 2020
This is what attendees can learn from the experts in the .NET scene:
- From .NET Framework to .NET Core to .NET 5.0: What does this mean for migration and how big is the effort?
- What’s new in .NET 5.0?
- New Features: Discover ASP.NET Core 5.0 and Blazor 5.0
- The most important linguistic innovations in C # 9
- Mobile development with .NET 5
- OR-Mapping mit Entity Framework Core 5.0
- WinUI 3 as an alternative to WPF and UWP
- Outlook on .NET 6.0
.
[ad_2]
Source link