Refactoring in reine Funktionen (C#)Refactoring Into Pure Functions (C#)

Ein wichtiger Aspekt bei dem Studium reiner funktionaler Transformationen besteht darin zu lernen, wie Code mit reinen Funktionen umgestaltet werden kann.An important aspect of pure functional transformations is learning how to refactor code using pure functions.

Hinweis

Nach der allgemeinen Nomenklatur bei der funktionalen Programmierung werden Programme mit reinen Funktionen umgestaltet.The common nomenclature in functional programming is that you refactor programs using pure functions. In Visual Basic und C++ geht dies mit der Verwendung von Funktionen in den jeweiligen Sprachen einher.In Visual Basic and C++, this aligns with the use of functions in the respective languages. In C# werden Funktionen aber als Methoden bezeichnet.However, in C#, functions are called methods. Im Rahmen dieser Erläuterung ist die reine Funktion als C#-Methode implementiert.For the purposes of this discussion, a pure function is implemented as a method in C#.

Wie bereits weiter oben erwähnt, besitzt eine reine Funktion zwei nützliche Eigenschaften:As noted previously in this section, a pure function has two useful characteristics:

  • Sie hat keine Nebenwirkungen.It has no side effects. Die Funktion ändert keine Variablen oder Daten irgendeines Typs außerhalb der Funktion.The function does not change any variables or the data of any type outside of the function.

  • Sie ist konsistent.It is consistent. Bei identischen Eingabedaten gibt die Funktion immer denselben Ausgabewert zurück.Given the same set of input data, it will always return the same output value.

Eine Möglichkeit des Umstiegs auf die funktionale Programmierung besteht darin, vorhandenen Code umzugestalten und so unnötige Nebenwirkungen und externe Abhängigkeiten abzuschaffen.One way of transitioning to functional programming is to refactor existing code to eliminate unnecessary side effects and external dependencies. Auf diese Weise können Sie Versionen von reinen Funktionen von vorhandenem Code erstellen.In this way, you can create pure function versions of existing code.

In diesem Thema wird erläutert, was eine reine Funktion ist und was nicht.This topic discusses what a pure function is and what it is not. Im Tutorial: Manipulating Content in a WordprocessingML Document (C#) (Tutorial: Bearbeiten von Inhalten in einem WordprocessingML-Dokument (C#)) wird gezeigt, wie Sie ein WordprocessingML-Dokument bearbeiten können. Außerdem enthält dieses Tutorial zwei Beispiele für das Umgestalten mithilfe einer reinen Funktion.The Tutorial: Manipulating Content in a WordprocessingML Document (C#) tutorial shows how to manipulate a WordprocessingML document, and includes two examples of how to refactor using a pure function.

Beseitigen von Nebenwirkungen und externen AbhängigkeitenEliminating Side Effects and External Dependencies

In den folgenden Beispielen werden zwei nicht reine Funktionen einer reinen Funktion gegenübergestellt.The following examples contrast two non-pure functions and a pure function.

Nicht reine Funktion, die einen Klassenmember ändertNon-Pure Function that Changes a Class Member

Im folgenden Code ist die HypenatedConcat-Funktion keine reine Funktion, da sie den aMember-Datenmember in der Klasse ändert:In the following code, the HypenatedConcat function is not a pure function, because it modifies the aMember data member in the class:

public class Program  
{  
    private static string aMember = "StringOne";  

    public static void HypenatedConcat(string appendStr)  
    {  
        aMember += '-' + appendStr;  
    }  

    public static void Main()  
    {  
        HypenatedConcat("StringTwo");  
        Console.WriteLine(aMember);  
    }  
}  

Dieser Code erzeugt die folgende Ausgabe:This code produces the following output:

StringOne-StringTwo  

Ob die zu ändernden Daten public-Zugriff oder private-Zugriff besitzen oder ein static-Member bzw. ein Instanzmember sind, spielt keine Rolle.Note that it is irrelevant whether the data being modified has public or private access, or is a static member or an instance member. Reine Funktionen führen zu keinerlei Änderungen an Daten außerhalb der Funktion.A pure function does not change any data outside of the function.

Nicht reine Funktion, die ein Argument ändertNon-Pure Function that Changes an Argument

Außerdem ist die folgende Version derselben Funktion keine reine Funktion, weil sie den Inhalt ihres Parameters, sb, ändert.Furthermore, the following version of this same function is not pure because it modifies the contents of its parameter, sb.

public class Program  
{  
    public static void HypenatedConcat(StringBuilder sb, String appendStr)  
    {  
        sb.Append('-' + appendStr);  
    }  

    public static void Main()  
    {  
        StringBuilder sb1 = new StringBuilder("StringOne");  
        HypenatedConcat(sb1, "StringTwo");  
        Console.WriteLine(sb1);  
    }  
}  

Diese Version des Programms produziert dieselbe Ausgabe wie die erste Version, weil die HypenatedConcat-Funktion durch Aufrufen der Append-Memberfunktion den Wert (Status) ihres ersten Parameters geändert hat.This version of the program produces the same output as the first version, because the HypenatedConcat function has changed the value (state) of its first parameter by invoking the Append member function. Beachten Sie, dass diese Änderung trotz der Tatsache auftritt, dass HypenatedConcat mit Wertparameterübergabe arbeitet.Note that this alteration occurs despite that fact that HypenatedConcat uses call-by-value parameter passing.

Wichtig

Wenn Sie bei Verweistypen einen Parameter nach Wert übergeben, führt dies zu einer Kopie des Verweises auf ein zu übergebendes Objekt.For reference types, if you pass a parameter by value, it results in a copy of the reference to an object being passed. Diese Kopie ist weiterhin mit denselben Instanzdaten wie der ursprüngliche Verweis verknüpft (so lange, bis die Verweisvariable einem neuen Objekt zugewiesen wird).This copy is still associated with the same instance data as the original reference (until the reference variable is assigned to a new object). Für das Ändern eines Parameters durch einen Parameter ist die Referenzparameterübergabe nicht unbedingt erforderlich.Call-by-reference is not necessarily required for a function to modify a parameter.

Reine FunktionPure Function

Die nächste Version des Programms zeigt, wie die HypenatedConcat-Funktion als reine Funktion implementiert werden kann.This next version of the program shows how to implement the HypenatedConcat function as a pure function.

class Program  
{  
    public static string HyphenatedConcat(string s, string appendStr)  
    {  
        return (s + '-' + appendStr);  
    }  

    public static void Main(string[] args)  
    {  
        string s1 = "StringOne";  
        string s2 = HyphenatedConcat(s1, "StringTwo");  
        Console.WriteLine(s2);  
    }  
}  

Auch diese Version erzeugt dieselbe Zeile in der Ausgabe: StringOne-StringTwo.Again, this version produces the same line of output: StringOne-StringTwo. Um den verketteten Wert beizubehalten, wird er in der Zwischenvariable s2 gespeichert.Note that to retain the concatenated value, it is stored in the intermediate variable s2.

Ein Ansatz, der sich als sehr hilfreich erweisen kann, besteht darin, Funktionen zu schreiben, die zwar lokal unrein (also lokale Variablen deklarieren und ändern), global aber rein sind.One approach that can be very useful is to write functions that are locally impure (that is, they declare and modify local variables) but are globally pure. Solche Funktionen besitzen viele der wünschenswerten Zusammensetzbarkeitseigenschaften, vermeiden dabei aber einige der komplizierteren Idiome der funktionalen Programmierung, z. B. die Notwendigkeit der Verwendung der Rekursion, wenn eine einfache Schleife dasselbe Ziel erreichen würde.Such functions have many of the desirable composability characteristics, but avoid some of the more convoluted functional programming idioms, such as having to use recursion when a simple loop would accomplish the same thing.

StandardabfrageoperatorenStandard Query Operators

Ein wichtiges Merkmal der Standardabfrageoperatoren besteht darin, dass sie als reine Funktionen implementiert sind.An important characteristic of the standard query operators is that they are implemented as pure functions.

Weitere Informationen finden Sie unter Übersicht über Standardabfrageoperatoren (C#).For more information, see Standard Query Operators Overview (C#).

Siehe auchSee Also

Introduction to Pure Functional Transformations (C#) (Einführung in reine funktionale Transformationen (c#))Introduction to Pure Functional Transformations (C#)
Funktionale Programmierung und Imperative Programmierung (C#)Functional Programming vs. Imperative Programming (C#)