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).