Überblick über C#

Die C#-Sprache ist die beliebteste Sprache für die .NET-Plattform, eine kostenlose, plattformübergreifende, Open Source-Entwicklungsumgebung. C#-Programme können auf vielen verschiedenen Geräten ausgeführt werden, von Internet der Dinge (IoT)-Geräten bis hin zur Cloud und überall dazwischen. Sie können Apps für Smartphones, Desktop und Laptopcomputer und Server schreiben.

C# ist eine plattformübergreifende universelle Sprache, mit der Entwickler*innen produktiv arbeiten und äußerst leistungsfähigen Code schreiben können. Mit Millionen von Entwickler*innen ist C# die beliebteste .NET-Sprache. C# wird im Ökosystem und in allen . NET-Workloads umfassend unterstützt. Basierend auf objektorientierten Prinzipien wurden zahlreiche Features aus anderen Paradigmen integriert – nicht zuletzt die funktionale Programmierung. Features auf niedriger Ebene unterstützen Szenarien mit hoher Effizienz, ohne unsicheren Code schreiben zu müssen. Der Großteil der .NET-Runtime und -Bibliotheken ist in C# geschrieben, und Fortschritte bei C# kommen häufig allen .NET-Entwickler*innen zugute.

Hello World

Das Programm „Hello, World“ wird für gewöhnlich zur Einführung einer Programmiersprache verwendet. Hier ist es in C#:

// This line prints "Hello, World" 
Console.WriteLine("Hello, World");

Die Zeile, die mit // beginnt, ist ein einzeiliger Kommentar. Einzeilige C#-Kommentare beginnen mit // und gehen bis zum Ende der aktuellen Zeile. C# unterstützt auch mehrzeilige Kommentare. Mehrzeile Kommentare beginnen mit /* und enden mit */. Die WriteLine-Methode der Console-Klasse, die sich im System-Namespace befindet, erzeugt die Ausgabe des Programms. Diese Klasse wird anhand der Standardklassenbibliotheken bereitgestellt, auf die standardmäßig automatisch in jedem C#-Programm verwiesen wird.

Im vorherigen Beispiel wird eine Form eines „Hallo Welt“-Programms mit Anweisungen der obersten Ebene gezeigt. In früheren C#-Versionen mussten Sie den Einstiegspunkt des Programms in einer Methode definieren. Dieses Format ist weiterhin gültig, und es wird in vielen vorhandenen C#-Beispielen angezeigt. Sie sollten auch mit diesem Formular vertraut sein, wie im folgenden Beispiel gezeigt:

using System;

class Hello
{
    static void Main()
    {
        // This line prints "Hello, World" 
        Console.WriteLine("Hello, World");
    }
}

Diese Version zeigt die Bausteine, die Sie in Ihren Programmen verwenden. Das Programm „Hello, World“ wird mit einer using-Richtlinie gestartet, die auf den System-Namespace verweist. Namespaces bieten eine hierarchische Möglichkeit zum Organisieren von C#-Programmen und -Bibliotheken. Namespaces enthalten Typen und andere Namespaces. Beispiel: Der System-Namespace enthält eine Reihe von Typen, wie etwa die Console-Klasse, auf die im Programm verwiesen wird, und viele andere Namespaces, wie etwa IO und Collections. Eine using-Richtlinie, die auf einen bestimmten Namespace verweist, ermöglicht die nicht qualifizierte Nutzung der Typen, die Member dieses Namespace sind. Aufgrund der using-Direktive kann das Programm Console.WriteLine als Abkürzung für System.Console.WriteLine verwenden. Im vorherigen Beispiel wurde dieser Namespace implizit eingeschlossen.

Die Hello-Klasse, die vom Programm „Hello, World“ deklariert wird, verfügt über einen einzelnen Member: die Main-Methode. Die Main-Methode wird mit dem Modifizierer static deklariert. Auch wenn Instanzmethoden mit dem Schlüsselwort this auf eine bestimmte einschließende Objektinstanz verweisen können, agieren statische Methoden ohne Verweis auf ein bestimmtes Objekt. Wenn keine Anweisungen auf oberster Ebene vorhanden sind, dient eine statische Methode namens „Main“ als Einstiegspunkt eines C#-Programms.

Beide Einstiegspunktformulare erzeugen einen gleichwertigen Code. Wenn Sie Anweisungen der obersten Ebene verwenden, synthetisiert der Compiler die enthaltende Klasse und Methode für den Einstiegspunkt des Programms.

Tipp

In den Beispielen in diesem Artikel erhalten Sie einen ersten Blick in C#-Code. Einige Beispiele zeigen möglicherweise Elemente von C# an, mit denen Sie nicht vertraut sind. Wenn Sie bereit sind, C# zu lernen, beginnen Sie mit unseren Einstiegstutorials, oder vertiefen Sie sich in die Links in den einzelnen Abschnitten. Wenn Sie Erfahrung mit Java, JavaScript, TypeScript oder Python haben, lesen Sie unsere Tipps, um die Informationen zu finden, die Sie benötigen, um C# schnell zu erlernen.

Vertraute C#-Funktionen

C# ist für Neulinge verfügbar, bietet jedoch erweiterte Funktionen für erfahrene Fachkräfte in der Entwicklung, die spezielle Anwendungen schreiben. Sie können schnell produktiv werden. Sie können weitere spezialisierte Techniken erlernen, wenn Sie sie für Ihre Anwendungen benötigen.

C#-Apps profitieren von der automatischen Speicherverwaltung von .NET Runtime. C#-Apps verwenden auch die umfangreichen Runtimebibliotheken, die vom .NET SDK bereitgestellt werden. Einige Komponenten sind plattformunabhängig, z. B. Dateisystembibliotheken, Datensammlungen und mathematische Bibliotheken. Andere sind spezifisch für eine einzelne Workload, z. B. die ASP.NET Core-Webbibliotheken oder die .NET MAUI UI-Bibliothek. Ein umfangreiches Open Source-Ökosystem unter NuGet erweitert die Bibliotheken, die Teil der Runtime sind. Diese Bibliotheken bieten noch mehr Komponenten, die Sie verwenden können.

C# befindet sich in der C-Familie der Sprachen. Die C#-Syntax sollte ihnen bekannt vorkommen, wenn Sie schon einmal C, C++, JavaScript oder Java verwendet haben. Wie alle Sprachen in der C-Familie definieren Semikolons (;) das Ende einer Anweisungen. Bei C#-Bezeichnern wird die Groß-/Kleinschreibung beachtet. Bei C# werden gleichen Klammern, { und }, Steuerelementanweisungen wie if, else und switch sowie Schleifenkonstrukte wie for und while verwendet. C# verfügt auch über eine foreach-Anweisung für einen beliebigen Sammlungstyp.

C# ist eine stark typisierte Sprache. Jede Variable, die Sie deklarieren, weist zur Kompilierungszeit einen bekannten Typ auf. Die Compiler- oder Bearbeitungstools teilen Ihnen mit, ob Sie diesen Typ falsch verwenden. Sie können diese Fehler beheben, bevor Sie Ihr Programm ausführen. Grundlegende Datentypen sind in die Sprache und Runtime integriert: Werttypen wie int, double und char, Verweistypen wie string, Arrays und andere Auflistungen. Während Sie Ihre Programme schreiben, erstellen Sie eigene Typen. Diese Typen können struct-Typen für Werte oder class-Typen, die objektorientiertes Verhalten definieren, sein. Sie können den record-Modifizierer entweder struct- oder class-Typen hinzufügen, sodass der Compiler Code für Gleichheitsvergleiche synthetisiert. Sie können auch interface-Definitionen erstellen, die einen Vertrag oder eine Gruppe von Membern definieren, die ein Typ zur Implementierung dieser Schnittstelle bereitstellen muss. Sie können auch generische Typen und Methoden definieren. Generics verwendet Typparameter, um einen Platzhalter für einen tatsächlichen Typ bereitzustellen, wenn er verwendet wird.

Beim Schreiben von Code definieren Sie Funktionen, die auch Methoden genannt werden, als Member von struct- und class-Typen. Diese Methoden definieren das Verhalten Ihrer Typen. Methoden können mit unterschiedlicher Anzahl oder Parametertypen überladen werden. Methoden können optional einen Wert zurückgeben. Zusätzlich zu Methoden können C#-Typen Eigenschaften aufweisen, bei denen es sich um Datenelemente handelt, die von Funktionen namens Zugriffsmethoden unterstützt werden. C#-Typen können Ereignisse definieren, wodurch ein Typ Abonnent*innen über wichtige Aktionen benachrichtigen kann. C# unterstützt objektorientierte Techniken wie Vererbung und Polymorphie für class-Typen.

Verwenden Sie Ausnahmen, um Fehler zu melden und zu behandeln. Diese Übung sollte Ihnen bekannt vorkommen, wenn Sie schon einmal C++ oder Java verwendet haben. Ihr Code löst eine Ausnahme aus, wenn er nicht die beabsichtigte Aktion ausführen kann. Anderer Code kann unabhängig von der Anzahl der Ebenen der Aufrufliste optional mithilfe eines try - catch-Blocks wiederhergestellt werden.

Typische C#-Funktionen

Einige Elemente von C# sind Ihnen möglicherweise weniger vertraut. Language Integrated Query (LINQ) stellt eine allgemeine musterbasierte Syntax zum Abfragen oder Transformieren einer beliebigen Sammlung von Daten bereit. LINQ vereint die Syntax zum Abfragen von In-Memory-Sammlungen, strukturierten Daten wie XML oder JSON, Datenbankspeicher und sogar cloudbasierten Daten-APIs. Sie lernen eine Syntax, und Sie können Daten unabhängig vom Speicher durchsuchen und bearbeiten. Die folgende Abfrage findet alle Kursteilnehmenden, deren Notendurchschnitt größer als 3,5 ist:

var honorRoll = from student in Students
                where student.GPA > 3.5
                select student;

Die vorangehende Abfrage funktioniert für viele Speichertypen, die durch Students dargestellt werden. Dabei kann es sich um eine Auflistung von Objekten, eine Datenbanktabelle, einen Cloudspeicher-Blob oder eine XML-Struktur handeln. Die gleiche Abfragesyntax funktioniert für alle Speichertypen.

Mit dem aufgabenbasierten asynchronen Programmiermodells können Sie Code schreiben, der sich so liest, als würde er synchron ausgeführt werden, obwohl er asynchron läuft. Er verwendet die und Schlüsselwörter async und await, um Methoden zu beschreiben, die asynchron sind, und wenn ein Ausdruck asynchron ausgewertet wird. Im folgenden Beispiel wird eine asynchrone Webanforderung erwartet. Nach Abschluss des asynchronen Vorgangs gibt die Methode die Länge der Antwort zurück:

public static async Task<int> GetPageLengthAsync(string endpoint)
{
    var client = new HttpClient();
    var uri = new Uri(endpoint);
    byte[] content = await client.GetByteArrayAsync(uri);
    return content.Length;
}

C# unterstützt auch eine await foreach-Anweisung zum Durchlaufen einer Sammlung, die von einem asynchronen Vorgang unterstützt wird, z. B. eine GraphQL-Paging-API. Im folgenden Beispiel werden Daten in Blöcken gelesen, wobei ein Iterator zurückgegeben wird, der Zugriff auf jedes Element bietet, wenn es verfügbar ist:

public static async IAsyncEnumerable<int> ReadSequence()
{
    int index = 0;
    while (index < 100)
    {
        int[] nextChunk = await GetNextChunk(index);
        if (nextChunk.Length == 0)
        {
            yield break;
        }
        foreach (var item in nextChunk)
        {
            yield return item;
        }
        index++;
    }
}

Aufrufer können die Sammlung mithilfe einer await foreach-Anweisung durchlaufen:

await foreach (var number in ReadSequence())
{
    Console.WriteLine(number);
}

C# stellt Musterabgleich bereit. Mit diesen Ausdrücken können Sie Daten prüfen und Entscheidungen basierend auf ihren Merkmalen treffen. Musterabgleich bietet eine hervorragende Syntax für die Ablaufsteuerung basierend auf Daten. Der folgende Code zeigt, wie Methoden für die booleschen Operatoren und, oder und xor mithilfe der Musterabgleichssyntax ausgedrückt werden können:

public static bool Or(bool left, bool right) =>
    (left, right) switch
    {
        (true, true) => true,
        (true, false) => true,
        (false, true) => true,
        (false, false) => false,
    };

public static bool And(bool left, bool right) =>
    (left, right) switch
    {
        (true, true) => true,
        (true, false) => false,
        (false, true) => false,
        (false, false) => false,
    };
public static bool Xor(bool left, bool right) =>
    (left, right) switch
    {
        (true, true) => false,
        (true, false) => true,
        (false, true) => true,
        (false, false) => false,
    };

Musterabgleichsausdrücke können mit _ als Catch all für jeden Wert vereinfacht werden. Das folgende Beispiel zeigt, wie Sie die - und-Methode vereinfachen können:

public static bool ReducedAnd(bool left, bool right) =>
    (left, right) switch
    {
        (true, true) => true,
        (_, _) => false,
    };

Als Teil des .NET-Ökosystems können Sie Visual Studio oder Visual Studio Code mit dem C#DevKit verwenden. Diese Tools bieten umfassende Einblicke in C#, einschließlich des von Ihnen geschriebenen Codes. Sie bieten auch Debugfunktionen.