C# Academy · Pelajaran

Closure dan Variabel yang Ditangkap

Lihat cara fungsi lokal menangkap keadaan.

Pelajaran 2 dari 413 langkah

Closure dan Variabel yang Ditangkap adalah pelajaran C# Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar C# Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus C# Academy mencakup 4 pelajaran total.

Penutupan atas Keadaan Lokal

Fungsi lokal (atau lambda) dapat membaca dan mengubah variabel dari metode yang memuatnya. Ini disebut penangkapan, dan fungsi beserta variabel yang ditangkapnya membentuk sebuah penutupan.

Menangkap Variabel

Fungsi lokal menggunakan factor dari metode yang memuatnya secara langsung. Fungsi tersebut tidak menerimanya sebagai parameter; fungsi tersebut menangkapnya dari lingkup di sekitarnya.

using System;

public class Program
{
    public static void Main()
    {
        int factor = 3;
        int Scale(int n) => n * factor; // captures factor

        Console.WriteLine(Scale(5));
        Console.WriteLine(Scale(10));
    }
}

Variabel yang Ditangkap adalah Referensi Aktif

Penutupan menangkap variabel, bukan cuplikan nilainya. Jika variabel berubah setelah fungsi dibuat, fungsi tersebut akan melihat nilai yang baru.

using System;

public class Program
{
    public static void Main()
    {
        int offset = 10;
        int Add(int n) => n + offset;

        Console.WriteLine(Add(1)); // 11
        offset = 100;
        Console.WriteLine(Add(1)); // 101 - sees updated offset
    }
}

Mengubah Variabel yang Ditangkap

Penutupan dapat menulis ke variabel yang ditangkap, dan perubahan tersebut juga terlihat di metode yang memuatnya. Hal ini membuat penutupan berguna untuk mengakumulasi keadaan.

using System;

public class Program
{
    public static void Main()
    {
        int count = 0;
        void Tick() => count++;

        Tick(); Tick(); Tick();
        Console.WriteLine(count); // 3
    }
}

Mengembalikan Penutupan

Ketika Anda mengembalikan lambda yang menangkap variabel lokal, variabel tersebut tetap ada setelah metode selesai. Keadaan yang ditangkap tetap hidup selama delegasi tersebut ada.

using System;

public class Program
{
    static Func<int> MakeCounter()
    {
        int count = 0;
        return () => ++count; // captures count
    }

    public static void Main()
    {
        var next = MakeCounter();
        Console.WriteLine(next());
        Console.WriteLine(next());
        Console.WriteLine(next());
    }
}

Penutupan yang Independen

Setiap pemanggilan fungsi pembuat membuat kumpulan variabel yang ditangkap dan baru. Dua penghitung yang dibuat dengan cara ini tidak saling mengganggu.

using System;

public class Program
{
    static Func<int> MakeCounter()
    {
        int count = 0;
        return () => ++count;
    }

    public static void Main()
    {
        var a = MakeCounter();
        var b = MakeCounter();
        Console.WriteLine(a()); // 1
        Console.WriteLine(a()); // 2
        Console.WriteLine(b()); // 1 - separate state
    }
}

Perbaikan Penangkapan pada foreach

Dalam C# modern, variabel perulangan foreach dibuat baru pada setiap iterasi, sehingga penutupan menangkap nilai yang diharapkan. Setiap lambda di bawah mengingat elemennya sendiri.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var actions = new List<Action>();
        foreach (var i in new[] { 1, 2, 3 })
            actions.Add(() => Console.WriteLine(i));

        foreach (var act in actions) act(); // prints 1, 2, 3
    }
}

Penangkapan dalam Perulangan for

Ini adalah jebakan klasik: satu variabel perulangan for digunakan bersama di semua iterasi, sehingga semua penutupan melihat nilai akhirnya. Salin variabel tersebut ke variabel lokal untuk setiap iterasi agar dapat menangkap nilai yang berbeda.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var actions = new List<Action>();
        for (int i = 0; i < 3; i++)
        {
            int copy = i; // fresh local each iteration
            actions.Add(() => Console.WriteLine(copy));
        }
        foreach (var act in actions) act(); // prints 0, 1, 2
    }
}

Penutupan Menangkap berdasarkan Referensi, Bukan Nilai

Karena penangkapan dilakukan berdasarkan referensi, perubahan pada nilai asli setelah penangkapan akan terlihat oleh penutupan. Ingat hal ini ketika waktu pembacaan dan penulisan menjadi penting.

using System;

public class Program
{
    public static void Main()
    {
        string message = "first";
        Action print = () => Console.WriteLine(message);

        print();          // first
        message = "second";
        print();          // second
    }
}

Penerapan Praktis: Perilaku yang Dapat Dikonfigurasi

Penutupan memungkinkan Anda membuat fungsi kecil yang telah dibekali konteks. Di sini, fungsi diskon menangkap suatu tarif dan menghasilkan kalkulator yang dapat digunakan kembali serta telah dikonfigurasi.

using System;

public class Program
{
    static Func<double, double> MakeDiscount(double rate)
        => price => price * (1 - rate);

    public static void Main()
    {
        var tenOff = MakeDiscount(0.10);
        var halfOff = MakeDiscount(0.50);
        Console.WriteLine(tenOff(100));
        Console.WriteLine(halfOff(100));
    }
}

Coba Sendiri

Buat fungsi pembuat penghitung yang penutupannya dikembalikan tetap menyimpan keadaan privat, lalu buat dua penghitung yang independen darinya.

using System;

public class Program
{
    static Func<int> MakeStepper(int step)
    {
        int current = 0;
        return () => { current += step; return current; }; // captures current and step
    }

    public static void Main()
    {
        var byTwos = MakeStepper(2);
        var byTens = MakeStepper(10);
        Console.WriteLine(byTwos()); // 2
        Console.WriteLine(byTwos()); // 4
        Console.WriteLine(byTens()); // 10 - separate state
    }
}

Pemeriksaan Singkat

Bernalarlah tentang cara kerja penangkapan.

Ringkasan

Penutupan menangkap variabel yang memuatnya berdasarkan referensi.

  • Fungsi melihat nilai variabel saat ini, termasuk perubahan yang terjadi kemudian.
  • Fungsi dapat mengubah variabel yang ditangkap dan berbagi keadaan dengan metode.
  • Penutupan yang dikembalikan membuat variabel yang ditangkapnya tetap hidup.
  • Gunakan variabel lokal untuk setiap iterasi dalam perulangan for agar dapat menangkap nilai yang berbeda.
Gratis untuk memulai

Belajar C# dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
93
Pelajaran
346

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Closure dan Variabel yang Ditangkap” gratis?

Ya — teks lengkap “Closure dan Variabel yang Ditangkap” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus C# Academy, upgrade ke CoddyKit PRO. Kursus C# Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Closure dan Variabel yang Ditangkap”?

Lihat cara fungsi lokal menangkap keadaan. Kamu berlatih C# Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai C# Academy?

Tidak diperlukan pengalaman sebelumnya. C# Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Closure dan Variabel yang Ditangkap” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran C# Academy ini?

Ya. Setiap pelajaran C# Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mendeklarasikan Fungsi Lokal
  2. Closure dan Variabel yang Ditangkap
  3. Fungsi Lokal Statis
  4. Fungsi Lokal vs Lambda
← Kembali ke C# Academy