Refaktor menjadi fungsi murni (LINQ ke XML)

Aspek penting dari transformasi fungsi murni adalah mempelajari cara merefaktor kode menggunakan fungsi murni.

Catatan

Nomenklatur umum dalam pemrograman fungsional adalah Anda merefaktor program menggunakan fungsi murni. Dalam Visual Basic dan C++, ini selaras dengan penggunaan fungsi dalam bahasa masing-masing. Namun, dalam C#, fungsi disebut metode. Untuk tujuan diskusi ini, fungsi murni diimplementasikan sebagai metode dalam C#.

Seperti disebutkan sebelumnya di bagian ini, fungsi murni memiliki dua karakteristik yang berguna:

  • Ini tidak memiliki efek samping. Fungsi ini tidak mengubah variabel atau data apa pun di luar fungsi.
  • Ini konsisten. Mengingat kumpulan data input yang sama, itu akan selalu mengembalikan nilai output yang sama.

Salah satu cara transisi ke pemrograman fungsional adalah dengan merefaktor kode yang ada untuk menghilangkan efek samping yang tidak perlu dan dependensi eksternal. Dengan cara ini, Anda dapat membuat versi fungsi murni dari kode yang ada.

Artikel ini membahas fungsi murni dan apa itu tidak. Tutorial: Memanipulasi konten dalam tutorial dokumen WordprocessingML menunjukkan cara memanipulasi dokumen WordprocessingML, dan menyertakan dua contoh cara merefaktor menggunakan fungsi murni.

Contoh berikut membedakan dua fungsi non-murni dan fungsi murni.

Contoh: Menerapkan fungsi non-murni yang mengubah anggota kelas statis

Dalam kode berikut, HyphenatedConcat fungsi ini bukan fungsi murni, karena memodifikasi aMember anggota kelas statis:

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

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

    public static void Main()
    {
        HyphenatedConcat("StringTwo");
        Console.WriteLine(aMember);
    }
}
Module Module1
    Dim aMember As String = "StringOne"

    Public Sub HyphenatedConcat(ByVal appendStr As String)
        aMember = aMember & "-" & appendStr
    End Sub

    Sub Main()
        HyphenatedConcat("StringTwo")
        Console.WriteLine(aMember)
    End Sub
End Module

Contoh ini menghasilkan output berikut:

StringOne-StringTwo

Perhatikan bahwa tidak relevan apakah data yang dimodifikasi memiliki public atau private mengakses, atau merupakan static anggota, anggota, shared atau anggota instans. Fungsi murni tidak mengubah data apa pun di luar fungsi.

Contoh: Menerapkan fungsi non-murni yang mengubah anggota kelas statis

Selain itu, versi berikut dari fungsi yang sama ini tidak murni karena memodifikasi konten parameternya, sb.

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

    public static void Main()
    {
        StringBuilder sb1 = new StringBuilder("StringOne");
        HyphenatedConcat(sb1, "StringTwo");
        Console.WriteLine(sb1);
    }
}
Module Module1
    Public Sub HyphenatedConcat(ByVal sb As StringBuilder, ByVal appendStr As String)
        sb.Append("-" & appendStr)
    End Sub

    Sub Main()
        Dim sb1 As StringBuilder = New StringBuilder("StringOne")
        HyphenatedConcat(sb1, "StringTwo")
        Console.WriteLine(sb1)
    End Sub
End Module

Versi program ini menghasilkan output yang sama dengan versi pertama, karena HyphenatedConcat fungsi telah mengubah nilai (status) parameter pertamanya dengan memanggil Append fungsi anggota. Perhatikan bahwa perubahan ini terjadi terlepas dari fakta bahwa HyphenatedConcat menggunakan parameter call-by-value yang lolos.

Penting

Untuk jenis referensi, jika Anda meneruskan parameter menurut nilai, itu menghasilkan salinan referensi ke objek yang diteruskan. Salinan ini masih dikaitkan dengan data instans yang sama dengan referensi asli (hingga variabel referensi ditetapkan ke objek baru). Panggilan demi referensi tidak selalu diperlukan agar fungsi memodifikasi parameter.

Contoh: Menerapkan fungsi murni

Versi program berikutnya ini menunjukkan cara mengimplementasikan HyphenatedConcat fungsi sebagai fungsi murni.

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);
    }
}
Module Module1
    Public Function HyphenatedConcat(ByVal s As String, ByVal appendStr As String) As String
        Return (s & "-" & appendStr)
    End Function

    Sub Main()
        Dim s1 As String = "StringOne"
        Dim s2 As String = HyphenatedConcat(s1, "StringTwo")
        Console.WriteLine(s2)
    End Sub
End Module

Sekali lagi, versi ini menghasilkan baris output yang sama: StringOne-StringTwo. Perhatikan bahwa untuk mempertahankan nilai yang digabungkan, nilai tersebut disimpan dalam variabel perantara s2.

Salah satu pendekatan yang bisa sangat berguna adalah menulis fungsi yang tidak murni secara lokal (yaitu, mereka mendeklarasikan dan memodifikasi variabel lokal) tetapi murni secara global. Fungsi-fungsi seperti itu memiliki banyak karakteristik komposabilitas yang diinginkan, tetapi hindari beberapa idiom pemrograman fungsional yang lebih berbelit,seperti harus menggunakan rekursi ketika perulangan sederhana akan mencapai hal yang sama.

Operator kueri standar

Karakteristik penting dari operator kueri standar adalah bahwa mereka diimplementasikan sebagai fungsi murni.

Untuk mendapatkan informasi selengkapnya, lihat Gambaran Umum Operator Kueri Standar (C#) atau Gambaran Umum Operator Kueri Standar (Visual Basic).

Lihat juga