Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 3 Min.

C# 7: Der richtige Einsatz von ref

Die neue Version von C# unterstützt nun Referenzen mittels des Schlüsselwortes ref. Damit lassen sich etwa schnelle Zugriffe auf Arrays programmieren, die noch dazu sicher sind.
Wer schon mal in C oder C++ entwickelt hat, kennt die Pointer-Spielereien, die man dort macht. Statt den Wert einer Variablen über den Stack zu übergeben, wird die Adresse der Speicherstelle über den Stack übergeben. Damit ist eine direkte Manipulation des Variableninhalts möglich - und allen möglichen Schweinereien Tür und Tor geöffnet. Der große Vorteil diese Vorgehens ist aber, dass damit Manipulation etwa an Array-Elementen immens schnell gehen. Die Gefahr ist aber groß, dass die falschen Speicherstellen verändert werden und das Programm dadurch fehlerhaft wird oder gar abstürzt. Diese Fehler zu finden, ist knifflig.Auch C# bietet eine begrenzte Möglichkeit des Referenzzugriffs. Das Zauberwort heißt unsafe.Was ist das Resultat von der Ausführung von folgendem Code?

class Program
{
  unsafe static void Main(string[] args)
  {
    int i = 42;
    MIncrement(&i);
    Console.WriteLine(i);
  }

  static unsafe void MIncrement(int* x)
  {
    *x = *x + 1;
  }
}
 
Richtig: 43. Da nicht der Wert, sondern die Referenz, also die Adresse der Variablen übergeben wird, verändert MIncrement den Inhalt dieser Variablen. Wie geschrieben, funktionierte das schon mit den ersten Versionen von .NET.

Und dann kam ref

Die Problematik von unsafe-Code hebt Marc Gravell in einem Blogpost hervor, in dem er auch die Möglichkeiten und Grenzen von ref erklärt.
  • Der Garbage Collector weigert sich auch nur zu versuchen, Pointern zu folgen.
  • Es kann unter Umständen beliebiger Code verändert werden.
  • das Schlüsselwort unsafe muss verwendet werden, was zu schwer aufzufindenden Fehlern führen kann.
  • außerdem funktionieren Pointer nur mit einer kleinen Untermenge an Typen.
Aus diesen Gründen sollte man - wenn benötigt - den Code mittels des neuen Schlüsselworts ref formulieren:
class Program
{
  static void Main(string[] args)
  {
    int i = 42;
    MIncrement(ref i);
    Console.WriteLine(i);
  }

  static unsafe void MIncrement(ref int x)
  {
    x = x + 1;
  }
} 
Es kommt das gleich Ergebnis heraus. Trotzdem kann der Garbage Collector aktiv werden und die Gefahr von Bugs ist nicht so groß.

Allerdings muss man - wie bei Referenzen immer - genau aufpassen, was man als Referenz übergibt. Handelt es sich hierbei etwa um eine lokale Variable, auf die außerhalb des Gültigkeitsbereich zugegriffen wird, wird der Compiler das nicht zulassen. Der folgende Code führt zu einem Fehler bei der Kompilierung: Das lokale Element i kann nicht als Verweis zurückgegeben werden, weil es kein lokales ref-Elelement ist.
ref int ReturnInvalidStackReference()
{
    int i = 32;
    return ref i; // can't do this
}
void WhatHappensHere()
{
    ref int v = ref ReturnInvalidStackReference();
    CallSomeOtherMethods(); // to use the stack
    int i = v; // dereference the ref
} 
Besonders interessant sind aber Referenzen in Bezug auf Arrays:
ref int GetArrayReference(int[] items, int index)
    => ref items[index];

void IncrementInsideArrayByRef()
{
    int[] values = { 1, 2, 3 };

    ref int item = ref GetArrayReference(values, 1);
    IncrementByRef(ref item);
    // what does this line print, and why?
    Console.WriteLine(string.Join(",", values));
} 
Damit lassen sich Array-Elemente manipulieren, ohne sie erst auf den Stack legen zu müssen.

Zu den Möglichkeiten schreibt Marc Gravell in seinem Blogpost.

Neueste Beiträge

Müssen Ziele SMART sein?
Wenn es um Ziele im Projektmanagement oder in der Führung einer Organisation geht, stoßen wir schnell und fast ausnahmslos auf das Akronym SMART. Was steckt dahinter, und kann es nicht auch sinnvolle Ziele geben, die nicht SMART sind?
8 Minuten
Arbeiten mit Tabellen und KI in Dataverse
Microsoft unterstützt die zentrale Datenmanagement-Lösung Dataverse in Power Apps mit KI-Features.
7 Minuten
6. Aug 2025
Managed DevOps Pools - Azure DevOps Pipelines Security
Agent Pools als Managed Service mit einfacher Integration in private Netzwerke und Authentisierung mittels Managed Identity tragen deutlich zur Sicherheit der Agent-Infrastruktur bei.
7 Minuten
7. Aug 2025
Miscellaneous

Das könnte Dich auch interessieren

Sicher ist sicher - Azure DevOps Pipelines Security
Als integraler Bestandteil der Entwicklungsumgebung ist Azure DevOps Pipelines oft Ziel von Angriffen. Da ist es gut zu wissen, wo die Schwachstellen des Systems liegen.
14 Minuten
16. Jun 2025
CodeProject.AI Server in neuer Version - Lokaler AI-Server
CodeProject.AI Server (jetzt in Version 2.1.10) ist ein lokal installierter, selbstgehosteter, schneller, kostenloser und Open Source Artificial Intelligence Server für jede Plattform und jede Sprache.
2 Minuten
Für Einsteiger: Backend-Webentwicklung mit .NET - Microsoft
Auf YouTube bietet Microsoft eine Videoserie für Einsteiger in die Backend-Webentwicklung mit .NET.
2 Minuten
13. Feb 2024
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige