0Pricing
C# Academy · درس

الإغلاقات والمتغيرات الملتقطة

تعرّفوا على كيفية التقاط الدوال المحلية للحالة

الإغلاقات والمتغيرات الملتقطة درس مجاني في C# Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C# Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C# Academy 4 دروس في المجموع.

الإغلاقات حول الحالة المحلية

يمكن لدالة محلية أو تعبير لامبدا قراءة المتغيرات الموجودة في الأسلوب الحاوي لها وتعديلها. ويُسمى ذلك الالتقاط، بينما تشكل الدالة مع المتغيرات التي تلتقطها إغلاقًا.

التقاط متغير

تستخدم الدالة المحلية factor من الأسلوب الحاوي لها مباشرةً. فهي لا تستلمه كمعلمة، بل تلتقطه من النطاق المحيط.

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));
    }
}

المتغيرات الملتقطة مراجع حية

يلتقط الإغلاق المتغير، وليس لقطة من قيمته. فإذا تغير المتغير بعد تعريف الدالة، فسترى الدالة القيمة الجديدة.

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
    }
}

تعديل المتغيرات الملتقطة

يمكن للإغلاق الكتابة إلى متغير ملتقط، ويظهر التغيير أيضًا في الأسلوب الحاوي له. وهذا يجعل الإغلاقات مفيدة لتجميع الحالة.

using System;

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

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

إرجاع إغلاق

عند إرجاع تعبير لامبدا التقط متغيرات محلية، تستمر تلك المتغيرات في الوجود بعد انتهاء الأسلوب. وتبقى الحالة الملتقطة ما دام المفوض موجودًا.

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());
    }
}

إغلاقات مستقلة

ينشئ كل استدعاء لمصنع مجموعة جديدة من المتغيرات الملتقطة. لذلك لا يتداخل عدادان أُنشئا بهذه الطريقة مع أحدهما الآخر.

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
    }
}

إصلاح الالتقاط في foreach

في C# الحديثة، يكون متغير حلقة foreach جديدًا في كل تكرار، ولذلك تلتقط الإغلاقات القيمة المتوقعة. ويتذكر كل تعبير لامبدا أدناه عنصره الخاص.

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
    }
}

الالتقاط في حلقة for

من المشكلات الشائعة أن متغير حلقة for واحدًا يُشارك بين التكرارات، ولذلك ترى جميع الإغلاقات قيمته النهائية. انسخه إلى متغير محلي خاص بكل تكرار لالتقاط قيم مميزة.

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
    }
}

تلتقط الإغلاقات بالمراجع لا بالقيم

بما أن الالتقاط يتم بالمرجع، فإن تعديل المتغير الأصلي بعد الالتقاط يظهر في الإغلاق. تذكر ذلك عندما يكون توقيت عمليات القراءة والكتابة مهمًا.

using System;

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

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

استخدام عملي: السلوك القابل للتهيئة

تتيح لك الإغلاقات إنشاء دوال صغيرة محمّلة مسبقًا بالسياق. في هذا المثال، تلتقط دالة الخصم معدلًا، فتنتج حاسبة قابلة لإعادة الاستخدام ومهيأة مسبقًا.

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));
    }
}

جرّب بنفسك

أنشئ مصنعًا للعدادات، بحيث يحتفظ الإغلاق المُرجع منه بحالة خاصة، ثم أنشئ منه عدادين مستقلين.

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
    }
}

تحقق سريع

حلّل كيفية عمل الالتقاط.

مراجعة

تلتقط الإغلاقات المتغيرات المحيطة بها بالمرجع.

  • ترى الدالة القيمة الحالية للمتغير، بما في ذلك التغييرات اللاحقة.
  • يمكنها تعديل المتغيرات الملتقطة ومشاركة الحالة مع الأسلوب.
  • تحافظ الإغلاقات المُرجعة على المتغيرات الملتقطة حيّة.
  • استخدم متغيرًا محليًا خاصًا بكل تكرار في حلقة for لالتقاط قيم مميزة.

الأسئلة الشائعة

هل درس «الإغلاقات والمتغيرات الملتقطة» مجاني؟

نعم — نص درس «الإغلاقات والمتغيرات الملتقطة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C# Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C# Academy 4 دروس في المجموع.

ماذا ستتعلم في «الإغلاقات والمتغيرات الملتقطة»؟

تعرّفوا على كيفية التقاط الدوال المحلية للحالة تتمرن على C# Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C# Academy؟

لا تُشترط خبرة سابقة. C# Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «الإغلاقات والمتغيرات الملتقطة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C# Academy هذا؟

نعم. كل درس في C# Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. التصريح عن الدوال المحلية
  2. الإغلاقات والمتغيرات الملتقطة
  3. الدوال المحلية الساكنة
  4. الدوال المحلية مقابل Lambdas
← العودة إلى C# Academy