C# und .NET 8 – Grundlagen, Profiwissen und Rezepte - Jürgen Kotz - E-Book

C# und .NET 8 – Grundlagen, Profiwissen und Rezepte E-Book

Jürgen Kotz

0,0

Beschreibung

Dieser komplett überarbeitete Klassiker der C#-/.NET-Programmierung bietet Ihnen Know-how und zahlreiche Rezepte, mit denen Sie häufig auftretende Probleme meistern. Einsteiger erhalten ein umfangreiches Tutorial zu den Grundlagen der C# 12-Programmierung mit Visual Studio, dem Profi liefert es fortgeschrittene Programmiertechniken zu allen wesentlichen Einsatzgebieten der Programmierung mit .NET 8. Zum sofortigen Ausprobieren finden Sie am Ende eines jeden Kapitels hochwertige Lösungen für nahezu jedes Problem.

Das Buch gliedert sich in einen Grundlagenteil zur Programmierung, eine Einführung in die Desktop-Programmierung (WPF, MAUI (Multi-platform App UI), einen Technologieteil zu fortgeschrittenen Themen sowie einen Teil zur Web-Programmierung (ASP.NET Core, MVC, Razor, Web-API, Blazor).

Es ist der ideale Begleiter für Ihre tägliche Arbeit und zugleich – dank der erfrischenden und unterhaltsamen Darstellung – eine spannende Lektüre, die Lust macht, Projekte auch in der Freizeit umzusetzen.

Sie lesen das E-Book in den Legimi-Apps auf:

Android
iOS
von Legimi
zertifizierten E-Readern
Kindle™-E-Readern
(für ausgewählte Pakete)

Seitenzahl: 983

Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:

Android
iOS
Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Jürgen KotzChristian Wenz

C# und .NET 8

Grundlagen, Profiwissen und Rezepte

Ihr Plus – digitale Zusatzinhalte!

Auf unserem Download-Portal finden Sie zu diesem Titel kostenloses Zusatzmaterial.

Geben Sie auf plus.hanser-fachbuch.de einfach diesen Code ein:

plus-W36m2-T9er4

Die Autoren:Jürgen Kotz, MünchenChristian Wenz, München

Alle in diesem Werk enthaltenen Informationen, Verfahren und Darstellungen wurden nach bestem Wissen zusammengestellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grund sind die im vorliegenden Werk enthaltenen Informationen mit keiner Verpflichtung oder Garantie irgendeiner Art verbunden. Autoren und Verlag übernehmen infolgedessen keine juristische Verantwortung und werden keine daraus folgende oder sonstige Haftung übernehmen, die auf irgendeine Art aus der Benutzung dieser Informationen – oder Teilen davon – entsteht. Ebenso wenig übernehmen Autoren und Verlag die Gewähr dafür, dass die beschriebenen Verfahren usw. frei von Schutzrechten Dritter sind. Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Werk berechtigt also auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann benutzt werden dürften.Die endgültige Entscheidung über die Eignung der Informationen für die vorgesehene Verwendung in einer bestimmten Anwendung liegt in der alleinigen Verantwortung des Nutzers.Aus Gründen der besseren Lesbarkeit wird auf die gleichzeitige Verwendung der Sprachformen männlich, weiblich und divers (m/w/d) verzichtet. Sämtliche Personenbezeichnungen gelten gleichermaßen für alle Geschlechter.

Bibliografische Information der Deutschen Nationalbibliothek:Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.

Dieses Werk ist urheberrechtlich geschützt.Alle Rechte, auch die der Übersetzung, des Nachdruckes und der Vervielfältigung des Buches, oder Teilen daraus, vorbehalten. Wir behalten uns auch eine Nutzung des Werks für Zwecke des Text- und Data Mining nach § 44b UrhG ausdrücklich vor. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlages in irgendeiner Form (Fotokopie, Mikrofilm oder ein anderes Verfahren) – auch nicht für Zwecke der Unterrichtsgestaltung – reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigt oder verbreitet werden.

© 2024 Carl Hanser Verlag München, www.hanser-fachbuch.deLektorat: Sylvia HasselbachCopy editing: Sandra Gottmann, WasserburgUmschlagdesign: Marc Müller-Bremer, München, www.rebranding.deUmschlagrealisation: Max KostopoulosTitelmotiv: © thinkstockphotos.de/liuzishanSatz: Eberl & Koesel Studio, Kempten

Print-ISBN:        978-3-446-47982-1E-Book-ISBN:   978-3-446-48060-5E-Pub-ISBN:       978-3-446-48178-7

Inhalt

Titelei

Impressum

Inhaltsverzeichnis

Vorwort

Zusatzmaterial online

Teil I: Grundlagen

1 .NET 8

1.1 Microsofts .NET-Technologie

1.1.1 Zur Geschichte von .NET

1.1.2 .NET-Features und Begriffe

1.2 .NET Core

1.2.1 Geschichte von .NET Core

1.2.2 LTS – Long Term Support und zukünftige Versionen

1.2.3 .NET Standard

1.3 Features von .NET 6

1.4 Features von .NET 7

1.5 Features von .NET 8

2 Einstieg in Visual Studio 2022

2.1 Die Installation von Visual Studio 2022

2.1.1 Überblick über die Produktpalette

2.1.2 Anforderungen an Hard- und Software

2.2 Unser allererstes C#-Programm

2.2.1 Vorbereitungen

2.2.2 Quellcode schreiben

2.2.3 Programm kompilieren und testen

2.2.4 Einige Erläuterungen zum Quellcode

2.2.5 Konsolenanwendungen sind out

2.3 Die Windows-Philosophie

2.3.1 Mensch-Rechner-Dialog

2.3.2 Objekt- und ereignisorientierte Programmierung

2.3.3 Programmieren mit Visual Studio 2022

2.4 Die Entwicklungsumgebung Visual Studio 2022

2.4.1 Neues Projekt

2.4.2 Die wichtigsten Fenster

2.4.3 Projektvorlagen in Visual Studio 2022 – Minimal APIs

2.5 Praxisbeispiele

2.5.1 Unsere erste Windows-Forms-Anwendung

2.5.2 Umrechnung Euro-Dollar

2.6 Neuerungen in Visual Studio 2022 Version 17.8

3 Grundlagen der Sprache C#

3.1 Grundbegriffe

3.1.1 Anweisungen

3.1.2 Bezeichner

3.1.3 Schlüsselwörter

3.1.4 Kommentare

3.2 Datentypen, Variablen und Konstanten

3.2.1 Fundamentale Typen

3.2.2 Wertetypen versus Verweistypen

3.2.3 Benennung von Variablen

3.2.4 Deklaration von Variablen

3.2.5 Typsuffixe

3.2.6 Zeichen und Zeichenketten

3.2.7 object-Datentyp

3.2.8 Konstanten deklarieren

3.2.9 Nullable Types

3.2.10 Typinferenz

3.2.11 Gültigkeitsbereiche und Sichtbarkeit

3.3 Konvertieren von Datentypen

3.3.1 Implizite und explizite Konvertierung

3.3.2 Welcher Datentyp passt zu welchem?

3.3.3 Konvertieren von string

3.3.4 Die Convert-Klasse

3.3.5 Die Parse-Methode

3.3.6 Boxing und Unboxing

3.4 Operatoren

3.4.1 Arithmetische Operatoren

3.4.2 Zuweisungsoperatoren

3.4.3 Logische Operatoren

3.4.4 Rangfolge der Operatoren

3.5 Kontrollstrukturen

3.5.1 Verzweigungsbefehle

3.5.2 Schleifenanweisungen

3.6 Benutzerdefinierte Datentypen

3.6.1 Enumerationen

3.6.2 Strukturen

3.7 Nutzerdefinierte Methoden

3.7.1 Methoden mit Rückgabewert

3.7.2 Methoden ohne Rückgabewert

3.7.3 Parameterübergabe mit ref

3.7.4 Parameterübergabe mit out

3.7.5 Methodenüberladung

3.7.6 Optionale Parameter

3.7.7 Benannte Parameter

3.8 Praxisbeispiele

3.8.1 Vom PAP zur Konsolenanwendung

3.8.2 Ein Konsolen- in ein Windows-Programm verwandeln

3.8.3 Schleifenanweisungen verstehen

3.8.4 Benutzerdefinierte Methoden überladen

3.8.5 Anwendungen von Visual Basic nach C# portieren

4 OOP-Konzepte

4.1 Kleine Einführung in die OOP

4.1.1 Historische Entwicklung

4.1.2 Grundbegriffe der OOP

4.1.3 Sichtbarkeit von Klassen und ihren Mitgliedern

4.1.4 Allgemeiner Aufbau einer Klasse

4.1.5 Das Erzeugen eines Objekts

4.1.6 Einführungsbeispiel

4.2 Eigenschaften

4.2.1 Eigenschaften mit Zugriffsmethoden kapseln

4.2.2 Berechnete Eigenschaften

4.2.3 Lese-/Schreibschutz

4.2.4 Property-Accessoren

4.2.5 Statische Felder/Eigenschaften

4.2.6 Einfache Eigenschaften automatisch implementieren

4.3 Methoden

4.3.1 Öffentliche und private Methoden

4.3.2 Überladene Methoden

4.3.3 Statische Methoden

4.4 Ereignisse

4.4.1 Ereignis hinzufügen

4.4.2 Ereignis verwenden

4.5 Arbeiten mit Konstruktor und Destruktor

4.5.1 Konstruktor und Objektinitialisierer

4.5.2 Destruktor und Garbage Collector

4.5.3 Mit using den Lebenszyklus des Objekts kapseln

4.6 Vererbung und Polymorphie

4.6.1 Method-Overriding

4.6.2 Klassen implementieren

4.6.3 Implementieren der Objekte

4.6.4 Ausblenden von Mitgliedern durch Vererbung

4.6.5 Allgemeine Hinweise und Regeln zur Vererbung

4.6.6 Polymorphes Verhalten

4.6.7 Die Rolle von System.Object

4.7 Spezielle Klassen

4.7.1 Abstrakte Klassen

4.7.2 Versiegelte Klassen

4.7.3 Partielle Klassen

4.7.4 Statische Klassen

4.8 Schnittstellen (Interfaces)

4.8.1 Definition einer Schnittstelle

4.8.2 Implementieren einer Schnittstelle

4.8.3 Abfragen, ob Schnittstelle vorhanden ist

4.8.4 Mehrere Schnittstellen implementieren

4.8.5 Schnittstellenprogrammierung ist ein weites Feld

4.9 Datensatztypen – Records

4.9.1 Definition eines Record

4.9.2 Mutable Properties

4.9.3 Nicht-destruktive Änderung

4.9.4 Dekonstruktion

4.10 Praxisbeispiele

4.10.1 Eigenschaften sinnvoll kapseln

4.10.2 Eine statische Klasse anwenden

4.10.3 Vom fetten zum schlanken Client

4.10.4 Schnittstellenvererbung verstehen

4.10.5 Rechner für komplexe Zahlen

4.10.6 Sortieren mit IComparable/IComparer

4.10.7 Einen Objektbaum in generischen Listen abspeichern

4.10.8 OOP beim Kartenspiel erlernen

4.10.9 Eine Klasse zur Matrizenrechnung entwickeln

4.10.10 Vererbung von Records

5 Arrays, Strings, Funktionen

5.1 Datenfelder (Arrays)

5.1.1 Array deklarieren

5.1.2 Array instanziieren

5.1.3 Array initialisieren

5.1.4 Zugriff auf Array-Elemente

5.1.5 Zugriff mittels Schleife

5.1.6 Mehrdimensionale Arrays

5.1.7 Zuweisen von Arrays

5.1.8 Arrays aus Strukturvariablen

5.1.9 Löschen und Umdimensionieren von Arrays

5.1.10 Eigenschaften und Methoden von Arrays

5.1.11 Übergabe von Arrays

5.2 Verarbeiten von Zeichenketten

5.2.1 Zuweisen von Strings

5.2.2 Eigenschaften und Methoden von String-Variablen

5.2.3 Wichtige Methoden der String-Klasse

5.2.4 Die StringBuilder-Klasse

5.3 Datums- und Zeitberechnungen

5.3.1 Die DateTime-Struktur

5.3.2 Wichtige Eigenschaften von DateTime-Variablen

5.3.3 Wichtige Methoden von DateTime-Variablen

5.3.4 Wichtige Mitglieder der DateTime-Struktur

5.3.5 Konvertieren von Datumstrings in DateTime-Werte

5.3.6 Die TimeSpan-Struktur

5.3.7 DateOnly und TimeOnly

5.4 Mathematische Funktionen

5.4.1 Überblick

5.4.2 Zahlen runden

5.4.3 Winkel umrechnen

5.4.4 Potenz- und Wurzeloperationen

5.4.5 Logarithmus und Exponentialfunktionen

5.4.6 Zufallszahlen erzeugen

5.4.7 Kreisberechnung

5.5 Zahlen- und Datumsformatierungen

5.5.1 Anwenden der ToString-Methode

5.5.2 Anwenden der Format-Methode

5.5.3 Stringinterpolation

5.6 Praxisbeispiele

5.6.1 Zeichenketten verarbeiten

5.6.2 Zeichenketten mit StringBuilder addieren

5.6.3 Methodenaufrufe mit Array-Parametern

6 Weitere Sprachfeatures

6.1 Namespaces (Namensräume)

6.1.1 Ein kleiner Überblick

6.1.2 Einen eigenen Namespace einrichten

6.1.3 Die using-Anweisung

6.1.4 Namespace Alias

6.1.5 Globale using-Anweisungen

6.2 Operatorenüberladung

6.2.1 Syntaxregeln

6.2.2 Praktische Anwendung

6.3 Collections (Auflistungen)

6.3.1 Die Schnittstelle IEnumerable

6.3.2 ArrayList

6.3.3 Hashtable

6.3.4 Indexer

6.4 Generics

6.4.1 Generics bieten Typsicherheit

6.4.2 Generische Methoden

6.4.3 yield – Iteratoren

6.5 Generische Collections

6.5.1 List-Collection statt ArrayList

6.5.2 Vorteile generischer Collections

6.5.3 Constraints

6.6 Das Prinzip der Delegates

6.6.1 Delegates sind Methodenzeiger

6.6.2 Einen Delegate-Typ deklarieren

6.6.3 Ein Delegate-Objekt erzeugen

6.6.4 Anonyme Methoden

6.6.5 Lambda-Ausdrücke

6.6.6 Lambda-Ausdrücke in der Task Parallel Library

6.6.7 Action<> und Func<>

6.7 Dynamische Programmierung

6.7.1 Wozu dynamische Programmierung?

6.7.2 Das Prinzip der dynamischen Programmierung

6.7.3 Optionale Parameter sind hilfreich

6.7.4 Kovarianz und Kontravarianz

6.8 Weitere Datentypen

6.8.1 BigInteger

6.8.2 Complex

6.8.3 Tuple<>

6.8.4 SortedSet<>

6.9 Praxisbeispiele

6.9.1 ArrayList versus generische List

6.9.2 Generische IEnumerable-Interfaces implementieren

6.9.3 Delegates, Func, anonyme Methoden, Lambda Expressions

7 Einführung in LINQ

7.1 LINQ-Grundlagen

7.1.1 Die LINQ-Architektur

7.1.2 Anonyme Typen

7.1.3 Erweiterungsmethoden

7.2 Abfragen mit LINQ to Objects

7.2.1 Grundlegendes zur LINQ-Syntax

7.2.2 Zwei alternative Schreibweisen von LINQ-Abfragen

7.2.3 Übersicht der wichtigsten Abfrageoperatoren

7.3 LINQ-Abfragen im Detail

7.3.1 Die Projektionsoperatoren Select und SelectMany

7.3.2 Der Restriktionsoperator Where

7.3.3 Die Sortierungsoperatoren OrderBy und ThenBy

7.3.4 Der Gruppierungsoperator GroupBy

7.3.5 Verknüpfen mit Join

7.3.6 Aggregat-Operatoren

7.3.7 Verzögertes Ausführen von LINQ-Abfragen

7.3.8 Konvertierungsmethoden

7.3.9 Abfragen mit PLINQ

7.4 Praxisbeispiele

7.4.1 Die Syntax von LINQ-Abfragen verstehen

7.4.2 Aggregat-Abfragen mit LINQ

7.4.3 LINQ im Schnelldurchgang erlernen

7.4.4 Strings mit LINQ abfragen und filtern

7.4.5 Duplikate aus einer Liste entfernen

7.4.6 Arrays mit LINQ initialisieren

7.4.7 Arrays per LINQ mit Zufallszahlen füllen

7.4.8 Einen String mit Wiederholmuster erzeugen

7.4.9 Mit LINQ Zahlen und Strings sortieren

7.4.10 Mit LINQ Collections von Objekten sortieren

7.4.11 Where – Deep Dive

8 Neuerungen von C# im Überblick

8.1 C# 4.0 – Visual Studio 2010

8.1.1 Datentyp dynamic

8.1.2 Benannte und optionale Parameter

8.1.3 Kovarianz und Kontravarianz

8.2 C# 5.0 – Visual Studio 2012

8.2.1 Async und Await

8.2.2 CallerInfo

8.3 Visual Studio 2013

8.4 C# 6.0 – Visual Studio 2015

8.4.1 String Interpolation

8.4.2 Schreibgeschützte AutoProperties

8.4.3 Initialisierer für AutoProperties

8.4.4 Expression Body Member

8.4.5 using static

8.4.6 Bedingter Nulloperator

8.4.7 Ausnahmenfilter

8.4.8 nameof-Ausdrücke

8.4.9 await in catch und finally

8.4.10 Indexinitialisierer

8.5 C# 7.0 – Visual Studio 2017

8.5.1 out-Variablen

8.5.2 Tupel

8.5.3 Mustervergleich

8.5.4 Discards

8.5.5 Lokale ref-Variablen und Rückgabetypen

8.5.6 Lokale Funktionen

8.5.7 Mehr Expression Body Member

8.5.8 throw-Ausdrücke

8.5.9 Verbesserung der numerischen literalen Syntax

8.6 C# 7.1 bis 7.3 – Visual Studio 2019

8.6.1 C# 7.1

8.6.2 C# 7.2

8.6.3 C# 7.3

8.6.4 Visual Studio 2019 – Live Share

8.7 C# 8.0

8.7.1 Standardschnittstellenmethoden

8.7.2 Vereinfachung von switch-Ausdrücken

8.7.3 Eigenschaftenmuster

8.7.4 Vereinfachte using-Ressourcenschutzblöcke

8.7.5 Null-Coalescing-Zuweisungen

8.7.6 Nullable Referenztypen

8.7.7 Indizes und Bereiche

8.7.8 Weitere Sprachneuerungen

8.8 C# 9.0

8.8.1 Records

8.8.2 Init-only Setter

8.8.3 Weitere Verbesserungen in Musterausdrücken

8.8.4 Weitere Sprachneuerungen

8.9 C# 10

8.9.1 Datensatzstrukturen

8.9.2 Globale using-Anweisungen

8.9.3 Weitere Sprachneuerungen

8.10 C# 11

8.10.1 Raw String Literals

8.10.2 Generische Mathematik

8.10.3 Generische Attribute

8.10.4 Listenmuster

8.10.5 Lokale Dateitypen

8.10.6 Required Member

8.10.7 Automatische Standardstrukturen

8.11 C# 12

8.11.1 Primäre Konstruktoren auch für Klassen und Strukturen

8.11.2 Sammlungsausdrücke

8.11.3 Weitere Sprachneuerungen

Teil II: Desktop-Anwendungen

9 Einführung in WPF

9.1 Einführung

9.1.1 Was kann eine WPF-Anwendung?

9.1.2 Die eXtensible Application Markup Language

9.1.3 Unsere erste XAML-Anwendung

9.1.4 Zielplattformen

9.1.5 Applikationstypen

9.1.6 Vor- und Nachteile von WPF-Anwendungen

9.1.7 Weitere Dateien im Überblick

9.2 Alles beginnt mit dem Layout

9.2.1 Allgemeines zum Layout

9.2.2 Positionieren von Steuerelementen

9.2.3 Canvas

9.2.4 StackPanel

9.2.5 DockPanel

9.2.6 WrapPanel

9.2.7 UniformGrid

9.2.8 Grid

9.2.9 ViewBox

9.2.10 TextBlock

9.3 Das WPF-Programm

9.3.1 Die App-Klasse

9.3.2 Das Startobjekt festlegen

9.3.3 Kommandozeilenparameter verarbeiten

9.3.4 Die Anwendung beenden

9.3.5 Auswerten von Anwendungsereignissen

9.4 Die Window-Klasse

9.4.1 Position und Größe festlegen

9.4.2 Rahmen und Beschriftung

9.4.3 Das Fenster-Icon ändern

9.4.4 Anzeige weiterer Fenster

9.4.5 Transparenz

9.4.6 Abstand zum Inhalt festlegen

9.4.7 Fenster ohne Fokus anzeigen

9.4.8 Ereignisfolge bei Fenstern

9.4.9 Ein paar Worte zur Schriftdarstellung

9.4.10 Ein paar Worte zur Darstellung von Controls

9.4.11 Wird mein Fenster komplett mit WPF gerendert?

10 Übersicht WPF-Controls

10.1 Allgemeingültige Eigenschaften

10.2 Label

10.3 Button, RepeatButton, ToggleButton

10.3.1 Schaltflächen für modale Dialoge

10.3.2 Schaltflächen mit Grafik

10.4 TextBox, PasswordBox

10.4.1 TextBox

10.4.2 PasswordBox

10.5 CheckBox

10.6 RadioButton

10.7 ListBox, ComboBox

10.7.1 ListBox

10.7.2 ComboBox

10.7.3 Den Content formatieren

10.8 Image

10.8.1 Grafik per XAML zuweisen

10.8.2 Grafik zur Laufzeit zuweisen

10.8.3 Bild aus Datei laden

10.8.4 Die Grafikskalierung beeinflussen

10.9 Slider, ScrollBar

10.9.1 Slider

10.9.2 ScrollBar

10.10 ScrollViewer

10.11 Menu, ContextMenu

10.11.1 Menu

10.11.2 Tastenkürzel

10.11.3 Grafiken

10.11.4 Weitere Möglichkeiten

10.11.5 ContextMenu

10.12 ToolBar

10.13 StatusBar, ProgressBar

10.13.1 StatusBar

10.13.2 ProgressBar

10.14 Border, GroupBox, BulletDecorator

10.14.1 Border

10.14.2 GroupBox

10.14.3 BulletDecorator

10.15 Expander, TabControl

10.15.1 Expander

10.15.2 TabControl

10.16 Popup

10.17 TreeView

10.18 ListView

10.19 DataGrid

10.20 Calendar/DatePicker

10.21 Ellipse, Rectangle, Line und Co.

10.21.1 Ellipse

10.21.2 Rectangle

10.21.3 Line

11 Wichtige WPF-Techniken

11.1 Eigenschaften

11.1.1 Abhängige Eigenschaften (Dependency Properties)

11.1.2 Angehängte Eigenschaften (Attached Properties)

11.2 Einsatz von Ressourcen

11.2.1 Was sind eigentlich Ressourcen?

11.2.2 Wo können Ressourcen gespeichert werden?

11.2.3 Wie definiere ich eine Ressource?

11.2.4 Statische und dynamische Ressourcen

11.2.5 Wie werden Ressourcen adressiert?

11.2.6 Systemressourcen einbinden

11.3 Das WPF-Ereignismodell

11.3.1 Einführung

11.3.2 Routed Events

11.3.3 Direkte Events

11.4 Verwendung von Commands

11.4.1 Einführung zu Commands

11.4.2 Verwendung vordefinierter Commands

11.4.3 Das Ziel des Commands

11.4.4 Vordefinierte Commands

11.4.5 Commands an Ereignismethoden binden

11.4.6 Wie kann ich ein Command per Code auslösen?

11.4.7 Command-Ausführung verhindern

11.5 Das WPF-Style-System

11.5.1 Übersicht

11.5.2 Benannte Styles

11.5.3 Typ-Styles

11.5.4 Styles anpassen und vererben

11.6 Verwenden von Triggern

11.6.1 Eigenschaften-Trigger (Property Triggers)

11.6.2 Ereignis-Trigger

11.6.3 Daten-Trigger

11.7 Einsatz von Templates

11.7.1 Neues Template erstellen

11.7.2 Template abrufen und verändern

11.8 Transformationen, Animationen, StoryBoards

11.8.1 Transformationen

11.8.2 Animationen mit dem StoryBoard realisieren

12 WPF-Datenbindung

12.1 Grundprinzip

12.1.1 Bindungsarten

12.1.2 Wann eigentlich wird die Quelle aktualisiert?

12.1.3 Geht es auch etwas langsamer?

12.1.4 Bindung zur Laufzeit realisieren

12.2 Binden an Objekte

12.2.1 Objekte im XAML-Code instanziieren

12.2.2 Verwenden der Instanz im C#-Quellcode

12.2.3 Anforderungen an die Quell-Klasse

12.2.4 Instanziieren von Objekten per C#-Code

12.3 Binden von Collections

12.3.1 Anforderung an die Collection

12.3.2 Einfache Anzeige

12.3.3 Navigieren zwischen den Objekten

12.3.4 Einfache Anzeige in einer ListBox

12.3.5 DataTemplates zur Anzeigeformatierung

12.3.6 Mehr zu List- und ComboBox

12.3.7 Verwendung der ListView

12.4 Noch einmal zurück zu den Details

12.4.1 Navigieren in den Daten

12.4.2 Sortieren

12.4.3 Filtern

12.4.4 Live Shaping

12.5 Anzeige von Datenbankinhalten

12.5.1 Installieren der benötigten NuGet-Pakete

12.5.2 Anlegen der Entitätsklassen

12.5.3 Die Programmoberfläche

12.5.4 Der Zugriff auf die Daten

12.6 Formatieren von Werten

12.6.1 IValueConverter

12.6.2 BindingBase.StringFormat-Eigenschaft

12.7 Das DataGrid als Universalwerkzeug

12.7.1 Grundlagen der Anzeige

12.7.2 UI-Virtualisierung

12.7.3 Spalten selbst definieren

12.7.4 Zusatzinformationen in den Zeilen anzeigen

12.7.5 Vom Betrachten zum Editieren

12.8 Praxisbeispiel – Collections in Hintergrundthreads füllen

13 .NET MAUI

13.1 Einführung

13.2 Was kann eine .NET MAUI-Anwendung?

13.3 Die erste .NET MAUI-App

13.4 Definieren einer eigenen View

13.5 Daten in MAUI anzeigen

13.6 Styles in MAUI

13.6.1 Styles

13.6.2 Themes

13.7 Navigation unter MAUI

Teil III: Technologien

14 Asynchrone Programmierung

14.1 Übersicht

14.1.1 Multitasking versus Multithreading

14.1.2 Deadlocks

14.1.3 Racing

14.2 Programmieren mit Threads

14.2.1 Einführungsbeispiel

14.2.2 Wichtige Thread-Methoden

14.2.3 Wichtige Thread-Eigenschaften

14.2.4 Einsatz der ThreadPool-Klasse

14.3 Sperrmechanismen

14.3.1 Threading ohne lock

14.3.2 Threading mit lock

14.3.3 Die Monitor-Klasse

14.3.4 Mutex

14.3.5 Methoden für die parallele Ausführung sperren

14.3.6 Semaphore

14.4 Interaktion mit der Programmoberfläche

14.4.1 Die Werkzeuge

14.4.2 Einzelne Steuerelemente mit Invoke aktualisieren (Windows Forms)

14.4.3 Mehrere Steuerelemente aktualisieren

14.4.4 Ist ein Invoke-Aufruf nötig?

14.4.5 Und was ist mit WPF?

14.5 Timer-Threads

14.6 Asynchrone Programmierentwurfsmuster

14.6.1 Kurzübersicht

14.6.2 Polling

14.6.3 Callback verwenden

14.6.4 Callback mit Parameterübergabe verwenden

14.6.5 Callback mit Zugriff auf die Programmoberfläche

14.7 Es geht auch einfacher – async und await

14.7.1 Der Weg von synchron zu asynchron

14.7.2 Achtung: Fehlerquellen!

14.7.3 Eigene asynchrone Methoden entwickeln

14.8 Asynchrone Streams

14.8.1 Datei erstellen

14.8.2 Datei lesen mit IAsyncEnumerable<T>

14.9 Praxisbeispiele

14.9.1 Prozess- und Thread-Informationen gewinnen

14.9.2 Ein externes Programm starten

15 Die Task Parallel Library

15.1 Überblick

15.1.1 Parallel-Programmierung

15.1.2 Möglichkeiten der TPL

15.1.3 Der CLR-Threadpool

15.2 Parallele Verarbeitung mit Parallel.Invoke

15.2.1 Aufrufvarianten

15.2.2 Einschränkungen

15.3 Verwendung von Parallel.For

15.3.1 Abbrechen der Verarbeitung

15.3.2 Auswerten des Verarbeitungsstatus

15.3.3 Und was ist mit anderen Iterator-Schrittweiten?

15.4 Collections mit Parallel.ForEach verarbeiten

15.5 Die Task-Klasse

15.5.1 Einen Task erzeugen

15.5.2 Den Task starten

15.5.3 Datenübergabe an den Task

15.5.4 Wie warte ich auf das Ende des Tasks?

15.5.5 Tasks mit Rückgabewerten

15.5.6 Die Verarbeitung abbrechen

15.5.7 Fehlerbehandlung

15.5.8 Weitere Eigenschaften

15.6 Zugriff auf das User Interface

15.6.1 Task-Ende und Zugriff auf die Oberfläche

15.6.2 Zugriff auf das UI aus dem Task heraus

15.7 Weitere Datenstrukturen im Überblick

15.7.1 Threadsichere Collections

15.7.2 Primitive für die Threadsynchronisation

15.8 Parallel LINQ (PLINQ)

15.9 Praxisbeispiele

15.9.1 BlockingCollection

15.9.2 PLINQ

16 Debugging, Fehlersuche und Fehlerbehandlung

16.1 Der Debugger

16.1.1 Allgemeine Beschreibung

16.1.2 Die wichtigsten Fenster

16.1.3 Debugging-Optionen

16.1.4 Praktisches Debugging am Beispiel

16.2 Arbeiten mit Debug und Trace

16.2.1 Wichtige Methoden von Debug und Trace

16.2.2 Besonderheiten der Trace-Klasse

16.2.3 TraceListener-Objekte

16.3 Caller Information

16.3.1 Attribute

16.3.2 Anwendung

16.4 Fehlerbehandlung

16.4.1 Anweisungen zur Fehlerbehandlung

16.4.2 try-catch

16.4.3 try-finally

16.4.4 Das Standardverhalten bei Ausnahmen festlegen

16.4.5 Die Exception-Klasse

16.4.6 Fehler/Ausnahmen auslösen

16.4.7 Eigene Fehlerklassen

16.4.8 Exceptionhandling zur Debugzeit

17 Entity Framework Core

17.1 Überblick

17.1.1 Objektrelationaler Mapper (ORM)

17.1.2 Provider

17.1.3 Relationale Beziehungen

17.1.4 Benötigte NuGet-Pakete

17.2 CodeFirst

17.2.1 CodeFirst aus Model

17.2.2 CodeFirst mittels ReverseEngineering von bestehender Datenbank

17.3 Migrationen

17.3.1 Initiale Migration bei ReverseEngineering

17.3.2 Weitere Migrationen

17.4 Lesen und Schreiben von Daten mit EF Core

17.5 Neuerungen in Entity Framework Core 7 und 8

17.5.1 JSON-Spalten

17.5.2 Bulk Updates

17.5.3 SaveChanges()

17.5.4 Mapping von Stored Procedures

17.5.5 Optimiertes SQL für Contains-Abfragen

17.5.6 Enums werden innerhalb von JSON-Spalten als ints gespeichert

17.5.7 Primitive Collections

17.6 Serialisierung mit System.Text.Json

17.7 Praxisbeispiele

17.7.1 Daten mit EF Core laden und als JSON speichern

17.7.2 Eine Datenbank mit EF Core anlegen und Testdaten generieren und anzeigen

Teil IV: Webanwendungen

18 Webanwendungen mit ASP.NET Core

18.1 Grundlagen

18.2 Razor Pages

18.2.1 Projektaufbau

18.2.2 Razor-Syntax

18.2.3 Layout-Vorlagen

18.2.4 Modelle für Razor Pages

18.2.5 Mit Formularen arbeiten

18.3 MVC

18.3.1 Projektaufbau

18.3.2 Action-Methoden

18.3.3 Zustandsmanagement

18.4 Praxisbeispiele

18.4.1 CRUD mit Entity Framework

18.4.2 Authentifizierung und Autorisierung

18.4.3 Zugriffsbeschränkung

19 Web APIs mit ASP.NET Core

19.1 REST

19.2 Vorlagen

19.3 Daten lesen

19.4 Daten schreiben, aktualisieren, löschen

19.5 Minimale APIs

19.6 Praxisbeispiele

19.6.1 Paginierung

19.6.2 XML statt JSON

19.6.3 CORS

20 Blazor

20.1 Hosting-Modelle

20.2 Projektvorlagen

20.3 Blazor-Komponenten

20.3.1 Code in/für Komponenten

20.3.2 Event-Handling

20.3.3 Datenbindung

20.4 Services und APIs aufrufen

20.5 Weitere Blazor-Features

20.5.1 Zustandsmanagement

20.5.2 JavaScript-Interoperabilität

20.5.3 Render-Modi und Streaming

20.6 Praxisbeispiele

20.6.1 Online-Status ermitteln

20.6.2 File-Uploads

20.6.3 Fehlerbehandlung

20.6.4 Datengrid

Anhang A: Glossar

Anhang B: Wichtige Dateiendungen

Vorwort

C# ist die seit langem von Microsoft propagierte Sprache, sie bietet die Möglichkeiten und Flexibilität von C++ und erlaubt trotzdem eine schnelle und unkomplizierte Programmierpraxis wie einst bei Visual Basic. C# ist (fast) genauso mächtig wie C++, wurde aber komplett neu auf objektorientierter Basis geschrieben.

In Jürgens Fall traten 2001 seine Tochter Julia und C# mit der ersten Beta-Version in sein Leben ein. Beide begleiten ihn jetzt seit über 20 Jahren. Aus seiner kleinen Tochter wurde mittlerweile eine erwachsene Frau, die mitten in ihrem Medizinstudium steht. Die Liebe zur IT konnte Jürgen ihr leider nicht ganz vermitteln, und C# ist definitiv auch zu einer erwachsenen Programmiersprache geworden. C# hat es auch geschafft laut dem TIOBE-Index zur Programmiersprache des Jahres 2023 gekürt zu werden.

Mit .NET 8 hat Microsoft jetzt auch die neueste Version von .NET veröffentlicht, bei der vor allem viele Neuerungen im Bereich Performance und Stabilität (vor allem für MAUI) implementiert wurden. Da diese Versionsnummer – wie alle geraden – einen „Long Term Support“ bietet, also drei Jahre lang Bugfixes und Sicherheitspatches, hat unser Buch eine gründliche Überarbeitung und Aktualisierung verdient. Der bewährte Aufbau bleibt natürlich erhalten, allerdings gibt es in jedem Kapitel Änderungen und Ergänzungen. Wir haben alle relevanten neuen Features von .NET 8 aufgenommen, beispielsweise die neuen Sprachfeatures von C# 12 oder die neuen Möglichkeiten von Blazor als Teil von ASP.NET Core 8. Sie erhalten somit weiterhin einen gründlichen Einstieg und Überblick über .NET, erfahren aber auch, was sich in den letzten Versionen getan hat.

C# ist das ideale Werkzeug zum Programmieren beliebiger Komponenten für .NET, beginnend bei WPF-, Web- und mobilen Anwendungen (auch für Android und iOS) bis hin zu systemnahen Applikationen.

Das vorliegende Buch ist ein Angebot für angehende wie auch für fortgeschrittene C#-Programmierer. Seine Philosophie knüpft an die vielen anderen Titel an, die in dieser Reihe in den vergangenen zwanzig Jahren zu verschiedenen Programmiersprachen erschienen sind:

       Programmieren lernt man nicht durch lineares Durcharbeiten eines Lehrbuchs, sondern nur durch unermüdliches Ausprobieren von Beispielen, verbunden mit ständigem Nachschlagen in der Referenz.

       Der Umfang einer modernen Sprache wie C# in Verbindung mit Visual Studio ist so gewaltig, dass ein seriöses Programmierbuch das Prinzip der Vollständigkeit aufgeben muss und nach dem Prinzip „so viel wie nötig“ sich lediglich eine „Initialisierungsfunktion“ auf die Fahnen schreiben kann.

Gegenüber anderen Büchern zur gleichen oder ähnlichen Thematik nimmt dieses Buch für sich in Anspruch, gleichzeitig Lehr- und Übungsbuch zu sein.

Zum Buchinhalt

Dieses Buch wagt den Spagat zwischen einem Grundlagen- und einem Profibuch. Sinn eines solchen Buches kann es nicht sein, eine umfassende Schritt-für-Schritt-Einführung in C# 12.0 zu liefern oder all die Informationen noch einmal zur Verfügung zu stellen, die Sie in der Produktdokumentation ohnehin schon finden und von denen Sie in der Regel nur ein Mausklick oder die F 1-Taste trennt.

       Für den Einsteiger möchten wir den einzig vernünftigen und gangbaren Weg beschreiten, nämlich nach dem Prinzip „so viel wie nötig“ eine schmale Schneise durch den Urwald der .NET-Programmierung mit C# schlagen, bis er eine Lichtung erreicht hat, die ihm erste Erfolgserlebnisse vermittelt.

       Für den Profi möchten wir in diesem Buch eine Vielzahl von Informationen und Knowhow bereitstellen, wonach er bisher in den mitgelieferten Dokumentationen, im Internet bzw. in anderen Büchern vergeblich gesucht hat.

Die Kapitel des Buches sind in vier Themenkomplexe gruppiert; online gibt es noch umfangreiches Zusatzmaterial, das auch immer wieder ergänzt wird:

1.      Grundlagen der Programmierung mit C# (Buch)

2.      Desktop-Anwendungen (Buch)

3.      Technologien (Buch)

4.      Webtechnologien (Buch)

5.      Windows-Forms-Anwendungen (online)

6.      Zugriff auf das Dateisystem (online)

7.      ADO.NET (online)

8.      XML (online)

Die Kapitel innerhalb eines Teils bilden einerseits eine logische Abfolge, können andererseits aber auch quergelesen werden. Im Praxisteil eines jeden Kapitels werden anhand realer Problemstellungen die behandelten Programmiertechniken im Zusammenhang demonstriert.

Nobody is perfect

Sie werden in diesem Buch nicht alles finden, was C# bzw. .NET 6 zu bieten haben. Manches ist sicher in einem anderen Spezialtitel ausführlicher beschrieben. Aber Sie halten mit diesem Buch einen überschaubaren Breitband-Mix in den Händen, der sowohl vertikal vom Einsteiger bis zum Profi als auch horizontal von den einfachen Sprachelementen bis hin zu komplexen Anwendungen jedem etwas bietet, ohne dabei den Blick auf das Wesentliche im .NET-Dschungel zu verlieren.

Wenn Sie Vorschläge oder Fragen zum Buch haben, können Sie uns gerne kontaktieren:

[email protected]

[email protected]

Wir hoffen, dass wir Ihnen mit diesem Buch einen nützlichen Begleiter bei der .NET-Programmierung zur Seite gestellt haben, der es verdient, seinen Platz nicht im Regal, sondern griffbereit neben dem Computer einzunehmen.

Vielen Dank!

Ein Buch – gerade, wenn es so umfangreich ist – ist stets Teamarbeit. Herzlichen Dank an unsere Lektorin Sylvia Hasselbach, mit der wir seit über 20 Jahren zusammenarbeiten dürfen, sowie an Kristin Rothe und Irene Weilhart. Sollten trotz aller Sorgfalt Fehler auffallen, so veröffentlichen wir diese als Errata auf der Buchseite auf www.hanser-fachbuch.de und auf https://plus.hanser-fachbuch.de bei den Codebeispielen. Lenny Kotz hat uns bei einigen der Grafiken im Buch unterstützt.

Der besondere Dank von Jürgen geht noch an Prof. Dr. med. Franz Bader mit seinem Team vom Isarklinikum sowie an Herrn PD Dr. med. O. J. Stötzer, ohne deren Einsatz dieses Buch nicht pünktlich hätte erscheinen können.

Jürgen Kotz und Christian Wenz

München, im Januar 2024

Zusatzmaterial online

Der Einfachheit halber werden im ersten Teil die Beispiele weiter mit Windows Forms oder als Konsolenanwendungen erstellt. Der zweite Teil des Buches behandelt dann ausführlich WPF sowie .NET MAUI und im dritten Teil „Technologien“ werden die Beispiele dann mit WPF oder auch einer Konsolenanwendung dargestellt. Der vierte Teil ist dann der Webtechnologie vorbehalten. Alle Beispieldaten dieses Buches und die mittlerweile zahlreichen Bonuskapitel können Sie online herunterladen.

Geben Sie auf

https://plus.hanser-fachbuch.de

diesen Code ein:

plus-W36m2-T9er4

Beim Nachvollziehen der Buchbeispiele beachten Sie bitte Folgendes:

       Kopieren Sie die Buchbeispiele auf die Festplatte. Wenn Sie auf die Projektmappendatei (*.sln) klicken, wird Visual Studio in der Regel automatisch geöffnet und das jeweilige Beispiel wird in die Entwicklungsumgebung geladen, wo Sie es z.B. mittels der F5-Taste kompilieren und starten können.

       Für einige Beispiele ist ein installierter Microsoft SQL Server Express LocalDB oder jegliche andere Instanz eines SQL-Servers erforderlich. Ersterer wird standardmäßig mit Visual Studio mit installiert.

       Beachten Sie die zu einigen Beispielen beigefügten Liesmich.txt-Dateien, die Sie auf besondere Probleme hinweisen.

Teil I:Grundlagen

       .NET 8 (Kapitel 1)

       Einstieg in Visual Studio 2022 Version 17.8 (Kapitel 2)

       Grundlagen der Sprache C# (Kapitel 3)

       OOP-Konzepte (Kapitel 4)

       Arrays, Strings, Funktionen (Kapitel 5)

       Weitere Sprachfeatures (Kapitel 6)

       Einführung in LINQ (Kapitel 7)

       Neuerungen von C# im Überblick (Kapitel 8)

1.NET 8

Mit .NET 8 ist im November 2023 die aktuellste Version des Microsoft Frameworks, das mittlerweile auf eine über 20-jährige Geschichte zurückblickt, erschienen. Seit der Version .NET 6 handelt sich dabei wieder um eine Version, welche das gesamte .NET-Universum wieder vereint, es gibt somit wieder ein „one“ .NET.

.NET 8 ist eine „Long Term Support“-Version (LTS) von .NET (weil gerade Versionsnummer) und wird somit bis zum November 2026 mit Fehlerbehebungen und Sicherheitsupdates unterstützt.

Mit dem .NET Framework können völlig unterschiedliche Applikationstypen (Desktop, Web, Mobile) in unterschiedlichen Programmiersprachen (C#, VB, F# etc.) entwickelt werden und egal was man macht, man hat eine einheitliche Funktionsbibliothek, eben das .NET Framework.

Im Jahre 2016 erschien parallel zum .NET Framework ein sogenanntes .NET Core Framework, das speziell für plattformübergreifende Webentwicklung konzipiert war. Keine Bindung somit mehr an Windows, sondern zeitgemäße plattformübergreifende Möglichkeiten (auch für mobile Plattformen wie iOs und Android), um seine Applikationen zu entwickeln und auch zu deployen. Da es sich bei .NET Core um Open Source handelte, hat Microsoft hier auch bewiesen, dass Open Source für Microsoft nicht nur ein Lippenbekenntnis ist, sondern ein wesentliches Fundament in der weiteren Entwicklung des Softwaregiganten.

Eigentlich war die Wiedervereinigung des klassischen .NET Frameworks mit den .NET-Core-Versionen bereits 2020 mit der Version 5.0 geplant, jedoch musste diese dann aufgrund der Coronapandemie um ein Jahr verschoben werden.

Somit wurden erst mit .NET 6 diese beiden Entwicklungsstränge (.NET und .NET Core) zusammengeführt und man hat wieder ein einheitliches Framework – laut Microsoft auch das performanteste .NET –, um seine Anwendungen zu schreiben. Nur die Entwicklung von Desktopapplikationen mit Windows Forms oder WPF ist noch an Windows gebunden, alle anderen Anwendungsmöglichkeiten sind plattformübergreifend.

Mit den seitdem erschienenen Versionen .NET 7 und nun eben auch .NET 8 hat Microsoft vor allem in Bezug auf Performance viele Besserungen durchgeführt.

Vor allem im Bereich der JSON-Serialisierung wurden im Namensraum System. Text.Json in der aktuellsten Version .NET 8 viele Serialisierungsverbesserungen eingearbeitet (mehr dazu in Kapitel 17).

1.1Microsofts .NET-Technologie

Ganz ohne Theorie geht nichts! In diesem leider etwas „trockenen“ Abschnitt werden Einsteiger mit der grundlegenden .NET-Philosophie und den damit verbundenen Konzepten, Begriffen und Features vertraut gemacht. Dazu dürfen Sie Ihrem Rechner ruhig einmal eine Pause gönnen.

1.1.1Zur Geschichte von .NET

Das Kürzel .NET ist die Bezeichnung für eine gemeinsame Plattform für viele Programmiersprachen. Beim Kompilieren von .NET-Programmen wird der jeweilige Quelltext in MSIL (Microsoft Intermediate Language) übersetzt. Es gibt nur ein gemeinsames Laufzeitsystem für alle Sprachen, die sogenannte CLR (Common Language Runtime), die die MSIL-Programme ausführt.

Die im Jahr 2002 eingeführte .NET-Technologie wurde notwendig, weil sich die Anforderungen an moderne Softwareentwicklung dramatisch verändert hatten, wobei das rasant wachsende Internet mit seinen hohen Ansprüchen an die Skalierbarkeit einer Anwendung, die Verteilbarkeit auf mehrere Schichten und ausreichende Sicherheit der hauptsächliche Motor war, sich nach einer grundlegend neuen Sprachkonzeption umzuschauen.

Mit .NET fand ein radikaler Umbruch in der Geschichte der Softwareentwicklung bei Microsoft statt. Nicht nur dass jetzt „echte“ objektorientierte Programmierung zum obersten Dogma erhoben wird, nein, auch eine langjährig bewährte Sprache wie das alte Visual Basic wurde völlig umgekrempelt und die einst gelobte COM-Technologie wurde zum Auslaufmodell erklärt!

HINWEIS: Dem unerfahrenen Leser mögen einige Ausführungen im Laufe dieses Kapitels noch sehr fremd sein. Machen Sie sich deswegen keine Sorgen und wenn Sie etwas nicht verstehen, kommen Sie einfach am Ende des Buches nochmals hierher zurück.

Warum eine eigene Programmiersprache?

C# wurde ausschließlich für das .NET Framework konzipiert, wobei versucht wurde, das Beste aus den etablierten Programmiersprachen Java, JavaScript, Visual Basic und C++ zu kombinieren, ohne aber deren Nachteile zu übernehmen.

Da sich die etablierten Sprachen nicht ohne größere Kompromisse an das .NET Framework anpassen ließen, haben die .NET-Entwickler die Gelegenheit beim Schopf gepackt und eine „maßgeschneiderte“ .NET-Sprache entwickelt. C# setzt auf dem .NET Framework auf und kommt ohne „faule“ Kompatibilitätskompromisse aus, wie sie z.B. teilweise bei Visual Basic erforderlich waren.

Als konsequent objektorientierte Sprache erfüllt C# folgende Kriterien:

       Abstraktion: Die Komplexität eines Geschäftsproblems ist beherrschbar, indem eine Menge von abstrakten Objekten identifiziert werden können, die mit dem Problem verknüpft sind.

       Kapselung: Die interne Implementation einer solchen Abstraktion wird innerhalb des Objekts versteckt.

       Polymorphie: Ein und dieselbe Methode kann auf mehrere Arten implementiert werden.

       Vererbung: Es wird nicht nur die Schnittstelle, sondern auch der Code einer Klasse vererbt (Implementationsvererbung statt der COM-basierten Schnittstellenvererbung).

Microsoft konnte natürlich nicht über Nacht die COM-Technologie auf die Müllkippe entsorgen, denn zu viele Programmierer wären dadurch auf immer und ewig verprellt worden und hätten sich frustriert einer stabileren Entwicklungsplattform zugewandt. Aus diesem Grund hat COM auch in .NET noch einige Zeit sein Gnadenbrot erhalten.

HINWEIS: Das gesamte Office-Paket wird auch weiterhin mit COM programmiert und die Schnittstellen zur Office-Automatisierung stehen über COM, das aus .NET heraus aufgerufen werden kann, zur Verfügung. Mittlerweile gibt es sogenannte PIA (Primary Interop-Assemblies)-Schnittstellen, die einen Wrapper für die COM-Schnittstelle bieten.

Ja, und das Ganze funktioniert auch weiterhin mit .NET 8.

Wie funktioniert eine .NET-Sprache?

Jeder in einer beliebigen .NET-Programmiersprache geschriebene Code wird beim Kompilieren in einen Zwischencode, den sogenannten MSIL-Code (Microsoft Intermediate Language Code), übersetzt, der unabhängig von der Plattform bzw. der verwendeten Hardware ist und dem man es auch nicht mehr ansieht, in welcher Sprache seine Source geschrieben wurde.

HINWEIS: Es gibt über 50 verschiedene Programmiersprachen für .NET. Sogar das ehrwürdige COBOL besitzt eine Version für .NET!

Erst wenn der MSIL-Code von einem Programm zur Ausführung genutzt werden soll, wird er vom Just-in-Time(JIT)-Compiler in Maschinencode übersetzt1. Ein .NET-Programm wird also vom Entwurf bis zu seiner Ausführung auf dem Zielrechner tatsächlich zweimal kompiliert (siehe Bild 1.1).

HINWEIS: Für die Installation eines Programms ist in der Regel lediglich die Weitergabe des MSIL-Codes erforderlich. Voraussetzung ist allerdings das Vorhandensein der .NET-Laufzeitumgebung (CLR), die Teil des .NET Frameworks ist, auf dem Zielrechner.

Bild 1.1Übersetzungsschritte einer .NET Programmiersprache

Eine der wesentlichsten Änderungen in .NET 7 mit einer Weiterführung in .NET 8 ist die Einführung eines AoT-Compilers (Ahead of Time). Bislang gab es in der .NET-Welt nur JiT-Compiler (Just in Time), die den erzeugten IL-Code (Intermediate Language-Code) während der Ausführung des Programms in nativen Maschinencode übersetzten. Bislang war es nur mit den Tools ngen.exe (klassisches .NET) bzw. crossgen.exe (.NET Core) möglich, nativen Maschinencode zu erstellen.

Nun hat man tatsächlich auch die Möglichkeit, bereits zur Compilezeit nativen Maschinencode zu erstellen.

Bei der Projektanlage (zumindest bei ausgewählten Projekttypen)) kann man bereits die Option native AOT-Veröffentlichung aktivieren anhaken (siehe Bild 1.2), und dadurch wird der folgende zusätzliche Eintrag in die Projektdatei geschrieben:

<PropertyGroup> <PublishAot>true</PublishAot> </PropertyGroup>

Dadurch aktiviert man die Option für die Ahead-of-Time Kompilierung.

Bild 1.2Neue AOT-Veröffentlichungsoption bei der Projektanlage

Wenn das Projekt dann veröffentlicht wird, erhält man nun die binären Dateien in nativem Maschinencode.

Leider ist diese Option noch nicht für alle Projektarten verfügbar, aber zumindest ein Anfang ist gemacht. Zum jetzigen Zeitpunkt ist AoT-Kompilierung nur für Konsolenanwendungen (und dabei auch nicht für alle Bibliotheken) verfügbar.

HINWEIS: In dem Zusammenhang sei erwähnt, dass C# laut dem TIOBE-Index (https://www.tiobe.com/tiobe-index/) die Programmiersprache des Jahres 2023 ist. Nach über zwei Jahrzehnten in den Top 10 in der Liste hat C# nun zum ersten Mal den Sprung an die Spitze geschafft.2

1.1.2.NET-Features und Begriffe

Mit Einführung von Microsofts .NET-Technologie prasselte auch eine Vielzahl neuer Begriffe auf die Entwicklergemeinde ein. Es werden hier nur die wichtigsten erklärt.

.NET Framework

.NET ist die Infrastruktur für die gesamte .NET-Plattform. Es handelt sich hierbei gleichermaßen um eine Entwurfs- wie um eine Laufzeitumgebung, in der Windows- und Web-Anwendungen erstellt und verteilt werden können.

Die nachfolgende Abbildung versucht, einen groben Überblick über die Komponenten des .NET Frameworks zu geben.

Zu den wichtigsten Komponenten des .NET Frameworks und den damit zusammenhängenden Begriffen zählen:

       Common Language Specification (CLS),

       Common Type System (CTS),

       Common Language Runtime (CLR),

       .NET-Klassenbibliothek,

       diverse Basisklassenbibliotheken wie ADO.NET und ASP.NET,

       diverse Compiler z.B. für C#, VB.NET usw.

Bild 1.3Komponenten des .NET Frameworks

In der obigen Abbildung sind die Entwicklungsstufen des ursprünglichen .NET Frameworks aufgezeichnet, die letzte klassische .NET Version 4.8 wurde 2019 veröffentlicht.

Im Folgenden sollen die einzelnen .NET-Bestandteile einer näheren Betrachtung unterzogen werden.

Die Common Language Specification (CLS)

Um den sprachunabhängigen MSIL-Zwischencode erzeugen zu können, müssen allgemein gültige Richtlinien und Standards für die .NET-Programmiersprachen existieren. Diese werden durch die Common Language Specification (CLS) definiert, die eine Reihe von Eigenschaften festlegt, die jede .NET-Programmiersprache erfüllen muss.

Bild 1.4CLS – Common Language Specification

HINWEIS: Ganz egal, mit welcher .NET-Programmiersprache Sie arbeiten, der Quellcode wird immer in ein und dieselbe Intermediate Language (MSIL) kompiliert.

Besonders für die Entwicklung von .NET-Anwendungen im Team haben die Standards der CLS weitreichende positive Konsequenzen, denn es ist nun zweitrangig, in welcher .NET-Programmiersprache Herr Müller die Komponente X und Herr Meier die Komponente Y schreibt. Alle Komponenten werden problemlos miteinander interagieren!

Auf einen wichtigen Bestandteil des CLS kommen wir im folgenden Abschnitt zu sprechen.

Das Common Type System (CTS)

Ein Kernbestandteil der CLS ist das Common Type System (CTS). Es definiert alle Typen3, die von der .NET-Laufzeitumgebung (CLR) unterstützt werden.

Alle diese Typen lassen sich in zwei Kategorien aufteilen:

       Wertetypen (werden auf dem Stack im Speicher abgelegt)

       Referenztypen (werden auf dem Heap im Speicher abgelegt)

Zu den Wertetypen gehören beispielsweise die ganzzahligen Datentypen und die Gleitkommazahlen. Zu den Referenztypen zählen die Objekte, die aus Klassen instanziiert wurden.

HINWEIS: Dass unter .NET auch die Wertetypen letztendlich als Objekte betrachtet und behandelt werden, liegt an einem als Boxing bezeichneten Verfahren, das die Umwandlung eines Wertetyps in einen Referenztyp zur Laufzeit besorgt.

Warum hat Microsoft mit dem heiligen Prinzip der Abwärtskompatibilität gebrochen und selbst die fundamentalen Datentypen einer Programmiersprache neu definiert?

Als Antwort kommen wir noch einmal auf eine wesentliche Säule der .NET-Philosophie zu sprechen, auf die durch CLS/CTS manifestierte Sprachunabhängigkeit und auf die Konsequenzen, die dieses Paradigma nach sich zieht.

Microsofts .NET-Entwickler hatten gar keine andere Wahl, denn um Probleme beim Zugriff auf sprachfremde Komponenten zu vermeiden und um eine sprachübergreifende Programmentwicklung überhaupt zu ermöglichen, mussten die Spezifikationen der Programmiersprachen durch die CLS einander angepasst werden. Dazu müssen alle wesentlichen sprachbeschreibenden Elemente – wie vor allem die Datentypen – in allen .NET-Programmiersprachen gleich sein.

Da .NET eine Normierung der Programmiersprachen erzwingt, verwischen die Grenzen zwischen den verschiedenen Sprachen und Sie brauchen nicht immer umzudenken, wenn Sie tatsächlich einmal auf eine andere .NET-Programmiersprache umsteigen wollen.

Als Lohn für die Mühen und den Mut, die eingefahrenen Gleise seiner altvertrauten Sprache zu verlassen, winken dem Entwickler wesentliche Vereinfachungen. So sind die Zeiten des alltäglichen Ärgers mit den Datentypen – wie z.B. bei der Übergabe eines Integers an eine C-DLL – endgültig vorbei. Bei so viel Licht gibt es natürlich auch Schatten. Mit einem der inzwischen zahlreich und kostenlos verfügbaren MSIL-Decompiler ist es sehr einfach möglich, aus einer EXE-Datei den Quellcode zu generieren. Wenn überhaupt, so ist es nur mit hohem Aufwand möglich, dass Sie als Programmierer Ihr Know-how vor der Konkurrenz schützen können. In Zeiten von Open Source sehen manche Unternehmen dieses Problem jedoch nicht mehr, anderen ist jedoch der Schutz des eigenen Quellcodes noch immer wichtig.

Die Common Language Runtime (CLR)

Die Laufzeitumgebung bzw. Common Language Runtime (CLR) ist die Umgebung, in der .NET-Programme auf dem Zielrechner ausgeführt werden. Sie muss auf einem Computer nur einmal installiert sein und schon laufen sämtliche .NET-Anwendungen, egal ob sie in C#, VB oder F# programmiert wurden. Die CLR zeichnet für die Ausführung der Anwendungen verantwortlich und kooperiert auf Basis des CTS mit der MSIL.

Mit ihren Fähigkeiten bildet die Common Language Runtime gewissermaßen den Kern von .NET. Den Code, der von der CLR ausgeführt wird, bezeichnet man auch als verwalteten bzw. Managed Code.

Die CLR ist innerhalb des .NET Frameworks nicht nur für das Ausführen von verwaltetem Code zuständig. Der Aufgabenbereich der CLR ist weitaus umfangreicher und umfasst zahlreiche Dienste, die als Bindeglied zwischen dem verwalteten MSIL-Code und dem Betriebssystem des Rechners die Anforderungen des .NET Frameworks sicherstellen, wie z.B.

       ClassLoader,

       Just-in-Time(JIT)-Compiler,

       ExceptionManager,

       Code Manager,

       Security Engine,

       Debug Machine,

       Thread Service,

       COM-Marshaller.

Die Verwendung der sprachneutralen MSIL erlaubt die Nutzung des CTS und der Basisklassen für alle .NET-Sprachen gleichermaßen. Einziger hardwareabhängiger Bestandteil des .NET Frameworks ist der Just-in-Time-Compiler. Deshalb kann der MSIL-Code im Prinzip frei zwischen allen Plattformen bzw. Geräten, für die ein .NET Framework existiert, ausgetauscht werden.

Namespaces

Alle Typen des .NET Frameworks werden in sogenannten Namensräumen (Namespaces) zusammengefasst. Unabhängig von irgendeiner Klassenhierarchie wird jede Klasse einem bestimmten Namensraum zugeordnet.

Die folgende Tabelle zeigt beispielhaft einige wichtige Namespaces für die Basisklassen des .NET Frameworks:

Namespace

. . . enthält Klassen für . . .

System. Windows.Forms

. . . Windows-basierte WinForms-Anwendungen

System. Collections

. . . Objekt-Arrays

System.Drawing

. . . die Grafikprogrammierung

System.Data

. . . den Datenbankzugriff

System. Web

. . . die Webprogrammierung

System.IO

. . . Ein- und Ausgabeoperationen

Mit den Namespaces hat auch der Ärger mit der Registrierung von (COM-)Komponenten bei Versionskonflikten sein Ende gefunden, denn eine unter .NET geschriebene Komponente wird von der .NET-Runtime nicht mehr über die ProgID der Klasse mithilfe der Registry lokalisiert, sondern über einen in der Runtime enthaltenen Mechanismus, der einen Namespace einer angeforderten Komponente sowie deren Version für das Heranziehen der „richtigen“ Komponente verwendet.

Assemblierungen

Unter einer Assemblierung (Assembly) versteht man eine Basiseinheit für die Verwaltung von Managed Code und für das Verteilen von Anwendungen. Sie kann sowohl aus einer einzelnen als auch aus mehreren Dateien (Modulen) bestehen. Eine solche Datei (.dll oder .exe) enthält MSIL-Code (kompilierter Zwischencode).

Die Klassenverwaltung in Form von selbst beschreibenden Assemblies vermeidet Versionskonflikte von Komponenten und ermöglicht vor allem dynamische Programminstallationen aus dem Internet. Statt der bei einer klassischen Installation bisher erforderlichen Einträge in die Windows-Registry genügt nunmehr einfaches Kopieren der Anwendung.

Normalerweise müssen Sie die Assemblierungen referenzieren, in denen die von Ihrem Programm verwendeten Typen bzw. Klassen enthalten sind. Eine Ausnahme ist die Assemblierung mscorlib.dll, welche die Basistypen des .NET Frameworks in verschiedenen Na­mensräumen umfasst (siehe obige Tabelle).

Zugriff auf COM-Komponenten

Verweise auf COM-DLLs werden so eingebunden, dass sie zur Entwurfszeit quasi wie .NET-Komponenten behandelt werden können.

Über das Menü Projekt/COM-Verweis hinzufügen erreichen Sie unter Visual Studio die Liste der verfügbaren COM-Bibliotheken. Nachdem Sie die gewünschte Bibliothek selektiert haben, können Sie die COM-Komponente wie gewohnt ansprechen.

HINWEIS: Wenn Sie COM-Objekte, wie z.B. alte ADO-Bibliotheken, in Ihre .NET-Projekte einbinden wollen, müssen Sie auf viele Vorteile von .NET verzichten. Durch die zusätzliche Interoperabilitätsschicht sinkt die Performance meist deutlich.

Metadaten und Reflexion

Das .NET Framework stellt im System.Reflection-Namespace einige Klassen bereit, die es erlauben, die Metadaten (Beschreibung bzw. Strukturinformationen) einer Assembly zur Laufzeit auszuwerten, womit z.B. eine Untersuchung aller dort enthaltenen Typen oder Methoden möglich ist.

Die Beschreibung durch die .NET-Metadaten ist allerdings wesentlich umfassender, als es in den gewohnten COM-Typbibliotheken üblich war. Außerdem werden die Metadaten direkt in der Assembly untergebracht, die dadurch selbstbeschreibend wird und z.B. auf Registry-Einträge verzichten kann. Metadaten können daher nicht versehentlich verloren gehen oder mit einer falschen Dateiversion kombiniert werden.

HINWEIS: Es gibt unter .NET nur noch eine einzige Stelle, an der sowohl der Programmcode als auch seine Beschreibung gespeichert werden!

Metadaten ermöglichen es, zur Laufzeit festzustellen, welche Typen benutzt und welche Methoden aufgerufen werden. Daher kann .NET die Umgebung an die Anwendung anpassen, sodass diese effizienter arbeitet.

Der Mechanismus zur Abfrage der Metadaten wird Reflexion (Reflection) genannt. Das .NET Framework bietet dazu eine ganze Reihe von Methoden an, mit denen jede Anwendung – nicht nur die CLR – die Metadaten von anderen Anwendungen abfragen kann.

Auch Entwicklungswerkzeuge wie Visual Studio verwenden die Reflexion, um z.B. den Mechanismus der IntelliSense zu implementieren. Sobald Sie einen Methodennamen eintippen, zeigt die IntelliSense eine Liste mit den Parametern der Methode an oder mit allen Elementen eines bestimmten Typs.

Weitere nützliche Werkzeuge, die auf der Basis von Reflexionsmethoden arbeiten, sind der IL-Disassembler (ILDASM) des .NET Frameworks oder ILSpy.

HINWEIS: Eine besondere Bedeutung hat Reflexion im Zusammenhang mit dem Auswerten von Attributen zur Laufzeit (siehe den folgenden Abschnitt).

Attribute

In vielen anderen Sprachen (VB 6, Delphi 7 etc.) versteht man Attribute als Variablen, die zu einem Objekt gehören und damit seinen Zustand beschreiben.

Unter .NET haben Attribute eine grundsätzlich andere Bedeutung: .NET-Attribute stellen einen Mechanismus dar, mit dem man Typen und Elemente einer Klasse schon beim Entwurf kommentieren und mit Informationen versorgen kann, die sich zur Laufzeit mittels Reflexion abfragen lassen.

Auf diese Weise können Sie eigenständige, selbstbeschreibende Komponenten entwickeln, ohne die erforderlichen Infos separat in Ressourcendateien oder Konstanten unterbringen zu müssen. So erhalten Sie mobilere Komponenten mit besserer Wartbarkeit und Erweiterbarkeit.

Man kann Attribute auch mit „Anmerkungen“ vergleichen, die man einzelnen Quellcode-Elementen, wie Klassen oder Methoden, „anheftet“. Solche Attribute (Annotations) gibt es eigentlich in jeder Programmiersprache, sie regeln z.B. die Sichtbarkeit eines bestimmten Datentyps. Allerdings waren diese Fähigkeiten bislang fest in den Compiler integriert, während sie unter .NET nunmehr direkt im Quellcode zugänglich sind. Das heißt, dass .NET-Attribute typsichere, erweiterbare Metadaten sind, die zur Laufzeit von der CLR (oder von beliebigen .NET-Anwendungen) ausgewertet werden können.

Mit Attributen können Sie Design-Informationen (z.B. zur Dokumentation), Laufzeit-Infos (z.B. Namen einer Datenbankspalte für ein Feld) oder sogar Verhaltensvorschriften für die Laufzeit (z.B. ob ein gegebenes Feld an einer Transaktion teilnehmen darf) definieren. Die Möglichkeiten sind quasi unbegrenzt.

Wenn Ihre Anwendung beispielsweise einen Teil der erforderlichen Informationen in der Registry abspeichert, muss bereits beim Entwurf festgelegt werden, wo die Registrierschlüssel abzulegen sind. Solche Informationen werden üblicherweise in Konstanten oder in einer Ressourcendatei untergebracht oder sogar fest in die Aufrufe der entsprechenden Registrierfunktionen eingebaut. Wesentliche Bestandteile der Klasse werden also von der übrigen Klassendefinition abgetrennt. Der Attribute-Mechanismus macht damit Schluss, denn er erlaubt es, derlei Informationen direkt an die Klassenelemente „anzuheften“, sodass letztendlich eine sich vollständig selbst beschreibende Komponente vorliegt.

Serialisierung

Fester Bestandteil des .NET Frameworks ist auch ein Mechanismus zur Serialisierung von Objekten. Unter Serialisierung versteht man das Umwandeln einer Objektinstanz in sequenzielle Daten, d.h. in binäre, XML- oder JSON-Daten mit dem Ziel, die Objekte als Datei permanent zu speichern oder über Netzwerke zu verschicken.

Auf umgekehrtem Weg rekonstruiert die Deserialisierung aus den Daten wieder die ursprüngliche Objektinstanz.

Das .NET Framework unterstützt drei verschiedene Serialisierungsmechanismen:

       Die Shallow-Serialisierung mit der Klasse System.Xml.Serialization.XmlSerializer.

       Die Deep-Serialisierung mit den Klassen BinaryFormatter und SoapFormatter aus dem System.Runtime.Serialization-Namespace.

       JSON-Serialisierung mittels der Klassen im Namensraum System.Text.Json

       oder alternativ (vor allem für die klassischen .NET Frameworks) zu System. Text.Json

       Durch das ladbare NuGet-Paket Newtonsoft.Json wird auch eine JSON-Serialisierung er­möglicht.

Aufgrund ihrer Einschränkungen (geschützte und private Objektfelder bleiben unberücksichtigt) ist die Shallow-Serialisierung für uns weniger interessant. Hingegen werden bei der Deep-Serialisierung alle Felder berücksichtigt – Bedingung ist lediglich die Kennzeichnung der Klasse mit dem Attribut [Serializable].

Das populärste Austauschformat momentan ist jedoch JSON. Die Funktionalität zur Serialisierung in dieses Format wird seit .NET 5 über eigene .NET-Framework-Klasse zur Verfügung gestellt, in vielen Teilen und vor allem bei den klassischen Framework-Versionen wird aber auch noch das Nuget-Paket Newtonsoft.Json verwendet.

Anwendungsgebiete der Serialisierung finden sich bei ASP.NET, ADO.NET, XML etc.

Multithreading

Multithreading ermöglicht es einer Anwendung, ihre Aktivitäten so aufzuteilen, dass diese unabhängig voneinander ausgeführt werden können, bei gleichzeitig besserer Auslastung der Prozessorzeit. Allgemein sind Threads keine Besonderheit von .NET, sondern auch in anderen Programmierumgebungen durchaus üblich.

Unter .NET laufen Threads in einem Umfeld, das Anwendungsdomäne genannt wird. Er­stellung und Einsatz erfolgen mithilfe der Klasse System.Threading.Thread.

Nicht in jedem Fall ist die Aufnahme zusätzlicher Threads die beste Lösung, da man sich dadurch auch zusätzliche Probleme einhandeln kann. So ist beim Umgang mit mehreren Threads die Threadsicherheit von größter Bedeutung. Das heißt, aus Sicht der Threads müssen die Objekte stets in einem gültigen Zustand vorliegen und das auch dann, wenn sie von mehreren Threads gleichzeitig benutzt werden.

Ab der .NET-Framework-Version 4.0 wurde das Konzept von Tasks (eine Art Hintergrundthread) mittels der TPL (Task Parallel Library) hinzugefügt. Mittels Tasks soll die Programmierung von asynchronen Funktionsaufrufen wesentlich vereinfacht werden. Die Klassen der TPL befinden sich im Namensraum System.Threading.Tasks.

Objektorientierte Programmierung

Last, but not least, möchten wir am Ende unseres Rundflugs über die .NET-Highlights noch einmal auf das allem zugrunde liegende OOP-Konzept verweisen, denn .NET ist komplett objektorientiert aufgebaut – unabhängig von der verwendeten Sprache oder der Zielumgebung, für die programmiert wird (Desktop- oder Web-Anwendung).

Jeder .NET-Code ist innerhalb einer Klasse verborgen und sogar einfache Variablen sind zu Objekten mutiert, die Eigenschaften und Methoden bereitstellen. Es ist deshalb wenig sinnvoll, mit der Einführung in die Sprache C# fortzufahren, ohne sich vorher mit dem Konzept der OOP vertraut gemacht zu haben (siehe Kapitel 4).

1.2.NET Core

Um die Konkurrenz nicht enteilen zu lassen, entschloss sich Microsoft neben dem klassischen .NET Framework das .NET Core Framework als Open-Source-Projekt zu entwickeln. Mit diesem Framework war es möglich, plattformübergreifende Webapplikationen und auch mobile Applikationen zu entwickeln.

1.2.1Geschichte von .NET Core

.NET Core war eine parallele Entwicklung, vornehmlich für Webapplikationen, die plattformübergreifend eingesetzt werden konnte und nicht mehr an das Windows-Betriebssystem gebunden war.

Bereits Mitte 2014 kündigte Microsoft .NET Core an, es dauerte dann aber noch zwei Jahre, bis .NET Core 1.0 final erschien. Der große Unterschied zum bisherigen klassischen .NET Framework bestand darin, dass nicht mehr auf das gesamte Framework referenziert wurde, sondern alle Bibliotheken in NuGet-Pakete aufgedröselt wurden, die dann – je nach dem, was im Projekt gebraucht wurde – diesem hinzugefügt wurden. Der Funktionsumfang dieser ersten Version enthielt natürlich nur ein Bruchteil des Funktionsumfangs des klassischen .NET Frameworks.

In zyklischen Abständen kamen dann weitere Versionen von 1.1 über 2.0, 2.1 sowie 2.2, und zu guter Letzt 3.0 und im Dezember 2019 .NET Core 3.1 hinzu, um die Lücken in der Funktionalität des bisherigen .NET Frameworks einigermaßen zu schließen. Alle Versionen wurden als .NET Core bezeichnet.

Dabei wurde der Support dieser Versionen in zwei Kategorien eingeteilt:

       LTS (Long Term Support ) für 3 Jahre

       Current für 18 Monate

Interessant dabei war, dass alle Versionen mit einer ungeraden Minor-Versionsummer (1.1, 2.1, 3.1) Long Term Support bekamen, während die anderen Versionen nur für 18 Monate von Microsoft supportet wurden.

Im November 2020 erschien dann .NET 5, jedoch nicht mit all den Features, die Microsoft geplant hatte. Einige Features wurden aufgrund der Coronapandemie auf die Version 6 verschoben. Obwohl .NET 5 der Nachfolger von .NET Core 3.1 war, wurde auf die Benennung .NET (Core) 4 verzichtet.

Zum einen wollte man keine Verwechslung mit der bisherigen klassischen Version des .NET Frameworks aufkommen lassen, das ja mittlerweile auch die Version 4 (zu diesem Zeitpunkt 4.8) erreicht hat. Und um klar darzustellen, dass es sich um die Basis aller weiteren .NET Frameworks handelt, wurde auch die Bezeichnung Core fallen gelassen.

Auch im klassischen .NET Framework wurde damit begonnen, wesentliche Bestandteile aus dem Framework auszulagern, um schnellere Produktzyklen gewährleisten zu können. Das bekannteste Beispiel dazu ist vermutlich Entity Framework, die von Microsoft empfohlene Datenbankzugriffstechnologie. Genauso wurde auch eine Core-Variante des Entity Frameworks entwickelt, die in Kapitel 17 beschrieben ist. Während bei der Framework-Version . NET 6 auf den Zusatz Core verzichtet wurde, werden wir diesen bei Entity Framework, zumindest zum jetzigen Stand, noch finden.

Bild 1.5Entwicklung der Frameworks

1.2.2LTS – Long Term Support und zukünftige Versionen

Microsoft hat mit Erscheinen von .NET 5 angekündigt, dass nunmehr jedes Jahr im November eine neue .NET-Version erscheint. Hierbei werden alle Versionen mit einer geraden Versionsnummer (wie .NET 6 oder .NET 8) Long Term Support erhalten, während der Support für die ungeraden Versionen wieder auf 18 Monate beschränkt ist.

Bild 1.6Geplanter .NET-Versionsverlauf

1.2.3.NET Standard

Dadurch, dass es jetzt plötzlich zwei nicht kompatible Framework-Versionen gab (klassisches .NET und .NET Core) hatten viele Entwickler folgendes Problem: Man wollte neue Komponenten mit der neuen Technologie entwickeln, aber natürlich konnte man die Codebase nicht von heute auf morgen einfach umstellen.

Eine .NET-Bibliothek konnte nicht in einem .NET Core-Projekt referenziert werden und umgekehrt, somit hatte man keine Möglichkeit, Bibliotheken zu entwickeln, die für beide Plattformen genutzt werden konnten.

Zu diesem Zweck wurde .NET Standard eingeführt. .NET Standard ist nicht noch ein zusätzliches Framework, sondern eine Spezifikation. In dieser Spezifikation wurde eine Reihe von Schnittstellen definiert, die in allen .NET-Plattformen implementiert werden müssen. Somit war .NET Standard der kleinste gemeinsame Nenner zwischen .NET, .NET Core und Xamarin 4(für die Entwicklung von mobilen Anwendungen unter iOs und Android).

Bibliotheken, die sowohl in .NET-Projekten wie auch in .NET-Core-Projekten genutzt werden sollten, konnte man somit in .NET Standard entwickeln.

Auch für .NET Standard gab es verschiedene Versionen, die immer mehr Schnittstellen definierten. Beginnend bei der Version 1.0, die noch sehr wenige Schnittstellen geboten hat, über die Version 1.6 hin bis zu 2.0 und 2.1.

Unterstützte die Version 1.6 noch ca. 13 000 Schnittstellen, so waren es bei der Version 2.0 schon 32 000 Schnittstellen, die man benutzen konnte. Allerdings wird für die .NET-Standard-2.0-Version auch bereits mindestens die Verwendung des .NET Frameworks in der Version 4.7.2 empfohlen (obwohl 4.6.1 offiziell unterstützt wird).

HINWEIS: Wir hoffen Sie mit diesen unzähligen unterschiedlichen Versionen und Versionsnummern nicht abgeschreckt zu haben, und können Sie beruhigen, dass wir mit der Aufzählung der unterschiedlichen Versionen durch sind.

1.3Features von .NET 6

So, dann wollen wir uns noch anschauen, was uns die weiterentwickelten .NET Frameworks an neuen Features bieten.

In puncto Desktopapplikationen hat man unterschiedlichste Frameworks zum Entwickeln von herkömmlichen, aber auch mobilen Apps. Wie schon in den Vorgängerversionen kann man WPF-Applikationen (siehe Kapitel 9-12) oder auch Windows-Forms-Applikationen (siehe Onlinekapitel) implementieren. Diese beiden Anwendungsarten sind aber weiterhin an die Windows-Plattform gebunden.

Komplett neu ist jedoch .NET MAUI (Multiplatform App UI), das als Nachfolger von Xamarin die Möglichkeit bietet, mobile Applikationen für iOS und Android zu entwickeln (siehe Kapitel 13). Eine Codebasis für die unterschiedlichen Plattformen nimmt dem Entwickler viel Arbeit ab.

Und dann kommen natürlich noch die Anwendungsarten für die Webentwicklung hinzu. Dieses sind die Kapitel ASP.NET Core (Kapitel 18), ASP.NET Web API (Kapitel 19) sowie Blazor (Kapitel 20).

Bild 1.7Überblick .NET 6

Außer diesen Anwendungsarten verspricht Microsoft unzählige Performanceverbesserungen, sodass es sich trotz der Plattformunabhängigkeit um das schnellste .NET handelt. Vor allem im Bereich Dateizugriff gibt es viele Verbesserungen, um das Lesen und Schreiben von Dateien zu optimieren.

Ein wesentlicher Zeitgewinn für alle Entwickler bietet Hot Reload. Hot Reload bietet die Möglichkeit, sowohl XAML- als auch C#-Code während der Laufzeit zu ändern und das Programm mit den geänderten Codeteilen weiterlaufen zu lassen, ohne jedes Mal das Programm neu starten zu müssen.

.NET 6 unterstützt auch alle Sprachfeatures von C# 10 (siehe Kapitel 8).

Minimal APIs ist ein weiterer Punkt, der dem Entwickler viele Codezeilen spart, jedoch auch teilweise kritisch gesehen wird, auch von den beiden Autoren dieses Buches. Dazu aber später mehr, wenn wir die geeigneten Beispiele dazu bringen und Sie sich dann Ihre eigene Meinung bilden können.

Um .NET 6 nutzen zu können, benötigen Sie Visual Studio 2022 (siehe Kapitel 2) oder Visual Studio Code. Eine Entwicklung mit .NET 6 unter Visual Studio 2019 oder früheren Versionen ist nicht möglich.

1.4Features von .NET 7

Wie bereits erwähnt, wurde mit .NET 7 zum allerersten Mal die Möglichkeit eines AOT-Compilers in Konsolenprojekten implementiert.

.NET 7 unterstützt auch den gesamten Sprachumfang der neuen C# Sprachversion 11, der in Kapitel 8 noch ausführlich vorgestellt wird.

Des Weiteren wurden einige Performanceverbesserungen durchgeführt und vor allem Verbesserungen an den Klassen im Namensraum System.Text.Json vorgenommen.

Zusätzlich gibt es neue oder verbesserte Klassen für folgende Einsatzmöglichkeiten (siehe Tabelle 1.1)

Tabelle 1.1 Neue und erweiterte Klassen in .NET 7

Einsatzmöglichkeiten

Klassennamen

Unterstützung für Mikro- und Nanosekunden

DateTime, DateTimeOffset TimeOnly, TimeSpanErweiterungen um die Properties Microsecond und Nanosecond

Unterstützung zum Zugriff auf Tar-Archive

Klassen im Namespace System.Formats.Tar

Unterstützung zum Lesen aller Daten aus einem Stream

Neue Methoden ReadExactly und ReadAtLeast in der Stream-Klasse

Neue Typkonverter

DateOnlyConverter, TimeOnlyConverter, Int128Converter, UInt128Converter, HalfConverter

Neues Attribut zum Auslesen, welche Syntax in einem String verwendet wird

StringSyntaxAttribute mit Konstanten wie zum Beispiel DateOnlyFormat, JsonFormat, Regex etc.

Eine komplette Zusammenfassung mit weiterführenden Links finden Sie unter https://learn.microsoft.com/de-de/dotnet/core/whats-new/dotnet-7.

Mit .NET 7 wurde auch eine neue Version 17.4 von Visual Studio 2022 veröffentlicht.

1.5Features von .NET 8

In der aktuellen Version des .NET Frameworks wurden die Möglichkeiten und Performance der AOT-Kompilierung weiter entwickelt und auch auf MAUI (zumindest für iOs und An­droid) übertragen.

Genauso wie in den Vorgängerversionen gibt es für .NET 8 eine neue C# Sprachversion 12, auch hier der Hinweis zur genaueren Darstellung in Kapitel 8.

Neben vielen kleinen Erweiterungen wurde auch der Namensraum System. Text.Json nochmals wesentlich erweitert (mehr dazu in Kapitel 17), und es gab auch sehr viele Performance- und Stabilisierungsverbesserungen für MAUI (mehr dazu dann in Kapitel 13).

Auch hier wollen wir die zusätzlichen Neuerungen von Klassen in Tabelle 1.2 als Überblick darstellen.

Tabelle 1.2 Neue und erweiterte Klassen in .NET 8

Einsatzmöglichkeiten

Klassennamen

Zufallsgeneratoren

Zusätzliche Methode GetItems in der Klasse Random, um nicht Zufallszahlen zu generieren, sondern um einen Eintrag aus einer Liste von Einträgen auszuwählen. Weitere Methode Shuffle, um die Reihenfolge von Listen wahlfrei zu mischen.

Verbesserung der Leistung von Collections

Neue Collection FrozenCollection<TKey, TValue>, bei der keine Schlüssel und Werte mehr verändert werden können, um ein schnelleres Lesen zu ermöglichen.

Datenvalidierung

Erweiterung von System. ComponentModel.DataAnnotations um folgende Attribute/Attributwerte:RangeAttribute.MinimumIsExclusive RangeAttribute.MaximumIsExclusive LengthAttribute Base64StringAttribute AllowedValuesAttribute DeniedValuesAttribute

Neue Metriken

MeterOptions

Kryptografie

Unterstützung von SHA-3-Hash-Grundelementen durch die Klassen SHA3_256, SHA3_384, SHA3_512 etc.

Unterstützung für Https-Proxies

Neue Funktionalität in den Klassen HttpClient und WebProxy

Streambasierte ZipFile-Funktionalität

Neue Überladungen in der Methode CreateFromDirectory der Klasse System. IO.Compression.ZipFile

DependencyInjection mit Schlüsseln

Erweiterungen der Methoden in Builder.Services (in ASP.NET Core)

GarbageCollection

Neue Funktionen zum Festlegen eines maximalen Arbeitsspeichergrenzwertes in der Klasse GC

Reflection nun auch für Funktionszeiger

System. Type besitzt nun eine Methode IsFunctionPointer.

Eine komplette Zusammenfassung mit weiterführenden Links finden Sie unter https://learn.microsoft.com/de-de/dotnet/core/whats-new/dotnet-8.

Mit .NET 8 wurde auch Version 17.8 von Visual Studio 2022 veröffentlicht, dazu aber gleich mehr im nächsten Kapitel.

1 Der Begriff „jeder Code“ schließt z.B. auch den Code der ASP.NET-Seiten ein.

2 Der TIOBE-Index ist ein Indikator über die Beliebtheit einer Programmiersprache und wird jeden Monat ermittelt. In der Berechnung des Ratings spielen vor allem die Anzahl von Suchen in Suchmaschinen, Angebote an Schulungen, Anzahl von Drittherstellern für die Sprache sowie Anzahl der Entwickler eine Rolle. Die Programmiersprache des Jahres ist dabei die Sprache mit dem größten Ratingzuwachs.

3 Unter .NET spricht man allgemein von Typen und meint damit Klassen, Interfaces und Datentypen, die als Wert übergeben werden.

4 Xamarin wird in .NET 6 durch .NET MAUI ersetzt. MAUI (Multiplatform App UI) wurde jedoch zur Veröffentlichung von .NET 6 nicht fertiggestellt und wird für das 2. Quartal 2022 angekündigt.

2Einstieg in Visual Studio 2022

Dieses Kapitel bietet Ihnen einen effektiven Schnelleinstieg in die Arbeit mit Visual Studio 2022. Gleich nachdem Sie die Hürden der Installation gemeistert haben, erstellen Sie mit C# Ihre ersten .NET-Anwendungen, werden dabei en passant mit den grundlegenden Features der Entwicklungsumgebung vertraut gemacht und nach dem Prinzip „so viel wie nötig“ in die .NET-Philosophie eingeweiht. Nach der Lektüre dieses Kapitels und dem Nachvollzug der abschließenden Praxisbeispiele sollte der Einsteiger über eine brauchbare Ausgangsbasis verfügen, um den sich vor ihm gewaltig auftürmenden Berg von Spezialkapiteln in Angriff zu nehmen.

HINWEIS: Für .NET 8 wird, wie auch für die Vorgängerversionen, weiterhin Visual Studio 2022 verwendet, Sie müssen aber mindestens die Version 17.8 installiert haben, um mit .NET 8 unter Visual Studio arbeiten zu können. Für .NET 7 benötigen Sie mindestens die Version 17.4.

Eine komplette Überarbeitung der Oberfläche ist für die Version 17.9 von Visual Studio 2022 vorgesehen, die jedoch zum Zeitpunkt der Erstellung dieses Buches erst in einer Preview-Version verfügbar ist.

2.1Die Installation von Visual Studio 2022

Ohne eine angemessen ausgestattete „Werkstatt“ ist die Lektüre dieses Buches nutzlos. Programmieren lernt man nur durch Beispiele, die man unmittelbar selbst am Rechner ausprobiert!

HINWEIS: Voraussetzung für ein erfolgreiches Studium dieses Buches ist ein Rechner mit einer lauffähigen Installation von Visual Studio 2022!

2.1.1Überblick über die Produktpalette

Für welches der im Folgenden aufgeführten Produkte man sich entscheidet, hängt von den eigenen Anforderungen und Wünschen ab und ist nicht zuletzt auch eine Frage des Geldbeutels.

HINWEIS: Bei Visual Studio 2022 handelt es sich erstmalig um eine 64-Bit-Applikation. Dies dürfte die Speicherproblematik, die man bei sehr großen Anwendungen in der Vergangenheit hatte, verschwinden lassen (vorausgesetzt Ihr Rechner besitzt genügend physikalischen Arbeitsspeicher).

Visual Studio 2022 Community

Bei dieser kostenfreien Version handelt es sich bereits um eine vollständig ausgestattete Entwicklungsumgebung für Windows-Desktop-, Web- und plattformübergreifende iOS-, An­droid- und Windows-Applikationen.

Sie kann auch für kommerzielle Projekte eingesetzt werden, wenn es sich dabei um Unternehmen mit weniger als 250 Mitarbeitern handelt.

HINWEIS: Der Inhalt dieses Buches kann komplett mit der Community Edition nachvollzogen werden!

Visual Studio 2022 Professional

Wie es der Name bereits suggeriert, handelt es sich bei diesem Standardpaket bereits um ein professionelles Werkzeug zur Entwicklung beliebiger Anwendungstypen im Team:

       Mit CodeLens ist ein leistungsstarkes Feature zum Verbessern der Produktivität Ihres Teams enthalten.

       Verschiedene Planungstools (Agile-Projekte, Teamräume, Diagramme usw.) dienen der Verbesserung der Team-Produktivität.

       Mit bestimmten MSDN-Abonnementleistungen erhalten Sie Zugang zu nützlicher Software für Entwicklung/Tests sowie Guthaben für die Azure-Cloudplattform

Visual Studio 2022 Enterprise

Hier handelt es sich um die Vollausstattung für Softwareentwickler, die im Team Anwendungen auf Enterprise-Niveau erstellen wollen. Neben allen Features der Professional-Version sind auch weitere Funktionen enthalten, die eine komplexe Datenbankentwicklung und eine durchgängige Qualitätssicherung ermöglichen sollen.

Die Screenshots in diesem Buch sind mit der Enterprise-Version erstellt. Wenn Ihnen also manche Menüpunkte, die auf dem Screenshot sichtbar sind, fehlen, liegt das an der unterschiedlichen Version. Zum Nachvollziehen werden Sie diese nicht benötigen.

2.1.2Anforderungen an Hard- und Software

Die folgende Auflistung kann lediglich eine Orientierungshilfe sein:

       Betriebssystem: Windows 10, Version 1909 oder höher, Windows 11, Windows Server 2022, Windows Server 2019, Windows Server 2016 (weitere Hinweise unter https://docs.microsoft.com/de-de/visualstudio/releases/2022/compatibility).

       Unterstützte Architekturen: 64-Bit (x64); ARM-Betriebssysteme werden nicht unterstützt.

       Prozessor: 1,8-GHz-Prozessor oder schneller; Quad-Core empfohlen.

       RAM: Mindestens 4 GB verfügbarer physischer Arbeitsspeicher; empfohlen werden 16 GB.

       Festplatte: Je nach Installation zwischen 20 – 50 GB Speicherplatzbedarf, es werden SSD-Platten empfohlen.

       Grafikkarte: WXGA mit einer Mindestauflösung von 1366 × 768 Pixeln, empfohlen WXGA mit 1920 × 1080 Pixel oder höher.

Die Parameter von Prozessor und RAM sind als untere Grenzwerte zu verstehen.

2.2Unser allererstes C#-Programm

Jeder Weg, und ist er noch so weit, beginnt mit dem ersten Schritt! Nachdem die Mühen der Installation gemeistert sind, wird es Zeit für ein allererstes C#-Programm. Wir verzichten allerdings auf das abgedroschene „Hello World“ und wollen gleich mit etwas Nützlicherem beginnen, nämlich der Umrechnung von Euro in Dollar.

Auch allein mit dem .NET Framework SDK, also ohne Visual Studio 2022, könnte man (zumindest rein theoretisch) vollwertige Programme entwickeln. Das wollen wir jetzt unter Beweis stellen, indem wir eine kleine Euro-Dollar-Applikation als sogenannte Konsolenanwendung – dem einfachsten Anwendungstyp – schreiben.

2.2.1Vorbereitungen

Voraussetzungen sind lediglich ein simpler Texteditor und der C#-Kommandozeilencompiler csc.exe.

Compilerpfad eintragen

Der C#-Compiler csc.exe befindet sich, ziemlich versteckt, im Verzeichnis

\\Windows\Microsoft.NET\Framework\v4.0.30319

Dieser Compiler ist der sogenannte Legacy-Compiler der klassischen .NET Frameworks.

Da das Kompilieren direkt an der Kommandozeile ausgeführt werden soll, werden wir csc.exe in den Windows-Pfad aufnehmen, um so seinen Aufruf von jedem Ordner des Systems aus zu ermöglichen.

Es gibt nun zwei Möglichkeiten, an der Kommandozeile mit dem gesetzten Pfad zur csc.exe zu arbeiten.

Die einfache Variante ist, Sie starten in der Programmgruppe Visual Studio 2022 (über das Startmenü) das Tool Developer Command Prompt for VS 2022. Daraufhin startet ein Konsolenfenster, in dem der korrekte Pfad bereits gesetzt ist.

Der aktuelle Compiler trägt den Namen Roslyn, und dieser Pfad (der auf unterschiedlichen Systemen an anderer Stelle steht) wird über den Aufruf des Tools Developer Command Prompt für VS 2022 automatisch gesetzt.

Oder Sie fügen den Pfad den Windows-Umgebungsvariablen hinzu. Das ist zwar etwas aufwendiger, aber Sie müssen das nur ein einziges Mal machen und können dann egal, von welcher Konsole aus, auf diesen Pfad direkt zugreifen. Gehen Sie dabei wie folgt vor:

       Sie finden den Dialog zur Einstellung der Path-Umgebungsvariablen in der Windows-Systemsteuerung, wenn Sie nach dem Begriff Path