নেট এ 'ক্লোজার' কী কী?


195

বন্ধ কী ? আমাদের কি তাদের নেট। নেট এ আছে?

যদি নেট। এ তাদের উপস্থিত থাকে তবে আপনি দয়া করে একটি কোড স্নিপেট সরবরাহ করতে পারেন (পছন্দ করে সি # তে) এটি ব্যাখ্যা করে?

উত্তর:


258

এই বিষয়টি নিয়ে আমার একটি নিবন্ধ রয়েছে । (এর প্রচুর উদাহরণ রয়েছে))

সংক্ষেপে, একটি বন্ধন কোডের একটি ব্লক যা পরবর্তী সময়ে কার্যকর করা যেতে পারে, তবে এটি পরিবেশটি বজায় রাখে যেখানে এটি তৈরি হয়েছিল প্রথমে - অর্থাৎ এটি এখনও পদ্ধতিটি তৈরি করেছে এর স্থানীয় ভেরিয়েবল ইত্যাদি ব্যবহার করতে পারে এমনকি তার পরেও পদ্ধতিটি কার্যকর করা শেষ করেছে।

বন্ধের সাধারণ বৈশিষ্ট্য বেনামে পদ্ধতি এবং ল্যাম্বদা এক্সপ্রেশন দ্বারা সি # তে প্রয়োগ করা হয়।

বেনামে পদ্ধতি ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হয়েছে:

using System;

class Test
{
    static void Main()
    {
        Action action = CreateAction();
        action();
        action();
    }

    static Action CreateAction()
    {
        int counter = 0;
        return delegate
        {
            // Yes, it could be done in one statement; 
            // but it is clearer like this.
            counter++;
            Console.WriteLine("counter={0}", counter);
        };
    }
}

আউটপুট:

counter=1
counter=2

এখানে আমরা দেখতে পাচ্ছি যে ক্রিয়েটএ্যাকশন দ্বারা ফিরে আসা ক্রিয়াকলাপটি এখনও কাউন্টার ভেরিয়েবলটিতে অ্যাক্সেস পেয়েছে এবং প্রকৃতপক্ষে ক্রিয়েটএ্যাকশন শেষ হয়ে গেলেও এটি এটিকে বাড়িয়ে তুলতে পারে।


57
ধন্যবাদ জন। বিটিডাব্লু, এমন কি এমন কিছু আছে যা আপনি জানেন না? নেট? :) প্রশ্ন থাকলে আপনি কার কাছে যাবেন?
বিকাশকারী

44
শেখার মতো আরও কিছু আছে :) আমি কেবল # সি এর মাধ্যমে সিএলআর পড়া শেষ করেছি - খুব তথ্যবহুল। তা ছাড়া আমি সাধারণত ডাব্লুসিএফ / বাঁধাই / এক্সপ্রেশন গাছের জন্য মার্ক গ্র্যাভেল এবং সি # ভাষার জিনিসগুলির জন্য এরিক লিপার্টকে জিজ্ঞাসা করি।
জন স্কিটি

2
আমি এটি লক্ষ্য করেছি, তবে আমি এখনও মনে করি এটি "কোডের একটি ব্লক যা পরবর্তী সময়ে মৃত্যুদন্ড কার্যকর করা যায়" হওয়া সম্পর্কে আপনার বক্তব্যটি সহজভাবে ভুল - এটি কার্যকর করার সাথে কিছুই করতে পারে না, ভেরিয়েবলের মান এবং মৃত্যুদন্ডের চেয়ে সুযোগের সাথে আরও কিছু করার নেই প্রতি সে।
জেসন বুটিং

11
আমি বলব যে মৃত্যুদন্ড কার্যকর না করা হলে ক্লোজারগুলি কার্যকর নয় এবং "পরবর্তী সময়ে" পরিবেশ ক্যাপচার করতে সক্ষম হওয়ার "বিজোড়তা" হাইলাইট করে (যা অন্যথায় মৃত্যুদন্ড কার্যকর করার সময় দ্বারা চলে যেতে পারে)। যদি আপনি কেবল অর্ধেক বাক্যটি উদ্ধৃত করেন তবে অবশ্যই এটি একটি অসম্পূর্ণ উত্তর।
জন স্কিটি

4
@ এসএলসি: হ্যাঁ, counterবর্ধিত হওয়ার জন্য উপলভ্য - সংকলকটি একটি শ্রেণি তৈরি করে যার মধ্যে একটি counterক্ষেত্র রয়েছে এবং যে কোনও কোড counterends শ্রেণীর উদাহরণ হিসাবে চলে ends
জন স্কিটি

22

আপনি যদি আগ্রহী হন যে সি # কীভাবে ক্লোজার প্রয়োগ করে "আমি উত্তরটি জানি (এর 42) ব্লগটি"

সংকলক ব্যাকগ্রাউন্ডে anoymous পদ্ধতি এবং ভেরিয়েবল জে encapصل করতে একটি বর্গ তৈরি করে

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    public <>c__DisplayClass2();
    public void <fillFunc>b__0()
    {
       Console.Write("{0} ", this.j);
    }
    public int j;
}

কাজের জন্য:

static void fillFunc(int count) {
    for (int i = 0; i < count; i++)
    {
        int j = i;
        funcArr[i] = delegate()
                     {
                         Console.Write("{0} ", j);
                     };
    } 
}

এটিকে রূপান্তর করা:

private static void fillFunc(int count)
{
    for (int i = 0; i < count; i++)
    {
        Program.<>c__DisplayClass1 class1 = new Program.<>c__DisplayClass1();
        class1.j = i;
        Program.funcArr[i] = new Func(class1.<fillFunc>b__0);
    }
}

হাই, ড্যানিল - আপনি উত্তরটি খুব দরকারী এবং আমি আপনার উত্তরের বাইরে গিয়ে অনুসরণ করতে চেয়েছিলাম তবে লিঙ্কটি নষ্ট হয়ে গেছে। দুর্ভাগ্যক্রমে, আমার গুগলফু কোথায় স্থানান্তরিত হয়েছে তা সন্ধান করার পক্ষে এটি যথেষ্ট ভাল নয়।
নক্স

10

বন্ধগুলি হ'ল কার্যকরী মান যা তাদের আসল সুযোগ থেকে পরিবর্তনশীল মানগুলিকে ধরে রাখে। সি # এগুলি বেনামে প্রতিনিধিদের আকারে ব্যবহার করতে পারে।

খুব সাধারণ উদাহরণের জন্য, এই সি # কোডটি নিন:

    delegate int testDel();

    static void Main(string[] args)
    {
        int foo = 4;
        testDel myClosure = delegate()
        {
            return foo;
        };
        int bar = myClosure();

    }

এটির শেষে, বারটি 4 তে সেট করা হবে এবং মাই ক্লোজার প্রতিনিধিটিকে প্রোগ্রামের অন্য কোথাও ব্যবহার করার জন্য পাস করা যেতে পারে।

বন্ধগুলি কার্যকরভাবে অনেক কাজে ব্যবহার করা যেতে পারে যেমন বিলম্বিত সম্পাদন বা ইন্টারফেস সহজ করার জন্য - লিনকুই মূলত ক্লোজার ব্যবহার করে তৈরি করা হয়। বেশিরভাগ বিকাশকারীদের পক্ষে এটি কার্যকরভাবে আসার উপায়টি ইভেন্ট হ্যান্ডলারগুলিকে গতিশীলভাবে তৈরি করা নিয়ন্ত্রণগুলিতে যুক্ত করছে - আপনি অন্য কোথাও ডেটা সঞ্চয় করার পরিবর্তে নিয়ন্ত্রণটি তাত্ক্ষণিকভাবে চালু করার সময় আচরণ যুক্ত করতে ক্লোজার ব্যবহার করতে পারেন।


10
Func<int, int> GetMultiplier(int a)
{
     return delegate(int b) { return a * b; } ;
}
//...
var fn2 = GetMultiplier(2);
var fn3 = GetMultiplier(3);
Console.WriteLine(fn2(2));  //outputs 4
Console.WriteLine(fn2(3));  //outputs 6
Console.WriteLine(fn3(2));  //outputs 6
Console.WriteLine(fn3(3));  //outputs 9

একটি বন্ধন এটি তৈরি করা ফাংশনের বাইরে পাস করা একটি বেনামি ফাংশন। এটি যে ফাংশনটিতে এটি ব্যবহার করে তা তৈরি হয় যা থেকে কোনও পরিবর্তনশীল বজায় রাখে।


4

এখানে সি # এর একটি স্বীকৃত উদাহরণ যা আমি জাভাস্ক্রিপ্টে অনুরূপ কোড থেকে তৈরি করেছি:

public delegate T Iterator<T>() where T : class;

public Iterator<T> CreateIterator<T>(IList<T> x) where T : class
{
        var i = 0; 
        return delegate { return (i < x.Count) ? x[i++] : null; };
}

সুতরাং, এখানে কিছু কোড যা দেখায় যে উপরের কোডটি কীভাবে ব্যবহার করতে হয় ...

var iterator = CreateIterator(new string[3] { "Foo", "Bar", "Baz"});

// So, although CreateIterator() has been called and returned, the variable 
// "i" within CreateIterator() will live on because of a closure created 
// within that method, so that every time the anonymous delegate returned 
// from it is called (by calling iterator()) it's value will increment.

string currentString;    
currentString = iterator(); // currentString is now "Foo"
currentString = iterator(); // currentString is now "Bar"
currentString = iterator(); // currentString is now "Baz"
currentString = iterator(); // currentString is now null

আশা করি এটি কিছুটা সহায়ক।


1
আপনি একটি উদাহরণ দিয়েছেন, কিন্তু সাধারণ সংজ্ঞা দেন নি। আমি এখানে আপনার মন্তব্যগুলি থেকে সংগ্রহ করেছি যে তারা 'সুযোগ সম্পর্কে আরও', তবে অবশ্যই এর চেয়ে আরও কিছু আছে কি?
লাড্ডেজ

2

মূলত ক্লোজার হ'ল কোডের একটি ব্লক যা আপনি কোনও ফাংশনের আর্গুমেন্ট হিসাবে পাস করতে পারেন। সি # বেনামী প্রতিনিধি আকারে ক্লোজার সমর্থন করে।

এখানে একটি সহজ উদাহরণ:
তালিকা.ফাইন্ড পদ্ধতি তালিকার আইটেমটি সন্ধানের জন্য কোডের টুকরো (ক্লোজার) গ্রহণ এবং সম্পাদন করতে পারে।

// Passing a block of code as a function argument
List<int> ints = new List<int> {1, 2, 3};
ints.Find(delegate(int value) { return value == 1; });

সি # 3.0 সিনট্যাক্স ব্যবহার করে আমরা এটিকে এটি লিখতে পারি:

ints.Find(value => value == 1);

1
আমি প্রযুক্তিগত হতে ঘৃণা করি, তবে বন্ধের সুযোগের সাথে আরও অনেক কিছু রয়েছে - একটি ক্লোজার বিভিন্ন উপায়ে তৈরি করা যেতে পারে তবে একটি বন্ধের উপায়টি নয়, এটিই শেষ।
জেসন বুটিং 16

2

একটি বন্ধন হ'ল যখন কোনও ফাংশন অন্য ফাংশনের (বা পদ্ধতি) ভিতরে সংজ্ঞায়িত হয় এবং এটি প্যারেন্ট পদ্ধতি থেকে ভেরিয়েবল ব্যবহার করে । ভেরিয়েবলের এই ব্যবহার যা কোনও পদ্ধতিতে অবস্থিত এবং এর মধ্যে নির্ধারিত কোনও ফাংশনে আবৃত থাকে, এটি ক্লোজার বলে।

মার্ক সিমেনের ব্লগ পোস্টে ক্লোজারগুলির কয়েকটি আকর্ষণীয় উদাহরণ রয়েছে যেখানে তিনি ওও এবং ফাংশনাল প্রোগ্রামিংয়ের মধ্যে একটি প্যারালিল করেন।

এবং এটি আরও বিশদ করতে

var workingDirectory = new DirectoryInfo(Environment.CurrentDirectory);//when this variable
Func<int, string> read = id =>
    {
        var path = Path.Combine(workingDirectory.FullName, id + ".txt");//is used inside this function
        return File.ReadAllText(path);
    };//the entire process is called a closure.

1

ক্লোজারগুলি এমন একটি কোডের অংশ যা তাদের বাইরে কোনও পরিবর্তনশীলকে বোঝায় (তাদের নীচে থেকে স্ট্যাকের উপরে), যা পরে বলা বা সম্পাদন করা যেতে পারে (যেমন কোনও ইভেন্ট বা প্রতিনিধি সংজ্ঞায়িত হওয়ার পরে এবং ভবিষ্যতে কোনও অনির্দিষ্ট সময়ে ডাকা যেতে পারে) ) ... কারণ বাহ্যিক ভেরিয়েবল যা কোড রেফারেন্সের অংশটি সুযোগের বাইরে চলে যায় (এবং অন্যথায় এটি হারিয়ে যেত), এটি কোডের অংশ দ্বারা (রেফারেন্স বলা হয়) দ্বারা উল্লেখ করা হয়েছে যা রানটাইমকে "ধরে রাখতে বলে" "কোডের ক্লোজার খণ্ডের দ্বারা আর এটির দরকার না হওয়া অবধি সুযোগে এই পরিবর্তনশীল ...


যেমন আমি অন্য কারোর ব্যাখ্যাতে ইঙ্গিত করেছি: প্রযুক্তিগত হতে আমি ঘৃণা করি তবে বন্ধের সুযোগের সাথে আরও অনেক কিছু রয়েছে - একটি বন্ধটি বিভিন্ন উপায়ে তৈরি করা যেতে পারে তবে একটি বন্ধের উপায় নয়, এটিই শেষ।
জেসন বুটিং

1
বন্ধগুলি আমার কাছে তুলনামূলকভাবে নতুন, সুতরাং এটি পুরোপুরি সম্ভব আমি ভুল বুঝেছি, তবে আমি সুযোগের অংশটি পেয়েছি .. আমার উত্তরটি সুযোগের চারপাশে কেন্দ্রীভূত। সুতরাং আমি অনুপস্থিত যা কোন মন্তব্যটি সংশোধন করার চেষ্টা করছে ... কোডের কিছু অংশ বাদে আর কী সুযোগ প্রাসঙ্গিক হতে পারে? (ফাংশন, বেনামে পদ্ধতি, বা যাই হোক না কেন)
চার্লস ব্রেটানা

কোনও "চলমান কোডের কিছু অংশ" কোনও পরিবর্তনশীল বা ইন-মেমোরির মানটিকে যেভাবে তার সুযোগের "বাহিরে" অ্যাক্সেস করতে পারে এমন বন্ধনের মূল কী এটি নয়, তার পরে চলকটি সাধারণত "সুযোগের বাইরে" চলে যেতে বা ধ্বংস করা উচিত ছিল ?
চার্লস ব্রেটানা

এবং জেসন, প্রযুক্তিগত হওয়ার বিষয়ে কোনও উদ্বেগ নেই, এই ক্লোজার ধারণাটি এমন একটি বিষয় যা আমি আমার মাথা গুটিয়ে ফেলার জন্য, সহকর্মীর সাথে জাভাস্ক্রিপ্ট বন্ধ হওয়ার বিষয়ে দীর্ঘ আলোচনার জন্য কিছুটা সময় নিয়েছিলাম ... তবে তিনি লিস্প বাদাম ছিলেন এবং আমি কখনই না তার ব্যাখ্যাগুলিতে বিমূর্ততাগুলি বেশ পেয়েছিল ...
চার্লস ব্রেটানা

0

আমি এটিও বোঝার চেষ্টা করছি, নীচে জাভাস্ক্রিপ্ট এবং সি # তে একই কোডের কোড স্নিপেটগুলি বন্ধ দেখানো হচ্ছে।

  1. টাইমসের সংখ্যা গণনা প্রতিটি ঘটনা ঘটেছিল বা প্রতিটি বোতাম ক্লিক করা হয় না।

জাভাস্ক্রিপ্ট:

var c = function ()
{
    var d = 0;

    function inner() {
      d++;
      alert(d);
  }

  return inner;
};

var a = c();
var b = c();

<body>
<input type=button value=call onClick="a()"/>
  <input type=button value=call onClick="b()"/>
</body>

সি #:

using System.IO;
using System;

class Program
{
    static void Main()
    {
      var a = new a();
      var b = new a();

       a.call();
       a.call();
       a.call();

       b.call();
       b.call();
       b.call();
    }
}

public class a {

    int b = 0;

    public  void call()
    {
      b++;
     Console.WriteLine(b);
    }
}
  1. গণনা ক্লিক ইভেন্টের মোট সংখ্যা হয়েছে বা নিয়ন্ত্রণ নির্বিশেষে ক্লিকের মোট সংখ্যা গণনা করুন।

javascript:

var c = function ()
{
    var d = 0;

    function inner() {
     d++;
     alert(d);
  }

  return inner;
};

var a = c();

<input type=button value=call onClick="a()"/>
  <input type=button value=call onClick="a()"/>

সি #:

using System.IO;
using System;

class Program
{
    static void Main()
    {
      var a = new a();
      var b = new a();

       a.call();
       a.call();
       a.call();

       b.call();
       b.call();
       b.call();
    }
}

public class a {

    static int b = 0;

    public void call()
    {
      b++;
     Console.WriteLine(b);
    }
}

0

নীল রঙের ঠিক বাইরে, সি # 7.0 সংক্ষেপে বইয়ের একটি সহজ এবং আরও বোঝার উত্তর।

প্রাক-আবশ্যক আপনার জানা উচিত : একটি ল্যাম্বডা এক্সপ্রেশনটি স্থানীয় ভেরিয়েবল এবং পদ্ধতির প্যারামিটারগুলিকে উল্লেখ করতে পারে যেখানে এটি সংজ্ঞায়িত হয়েছে (বাহ্যিক ভেরিয়েবল)।

    static void Main()
    {
    int factor = 2;
   //Here factor is the variable that takes part in lambda expression.
    Func<int, int> multiplier = n => n * factor;
    Console.WriteLine (multiplier (3)); // 6
    }

আসল অংশ : ল্যাম্বডা এক্সপ্রেশন দ্বারা রেফারেন্সযুক্ত আউটার ভেরিয়েবলগুলি ক্যাপচারড ভেরিয়েবলগুলি বলে। একটি ল্যাম্বডা এক্সপ্রেশন যা ভেরিয়েবল ক্যাপচার করে তাকে ক্লোজার বলে।

সর্বশেষ পয়েন্টটি লক্ষণীয় : ক্যাপচারড ভেরিয়েবলগুলি মূল্যায়ন করা হয় যখন ডেলিগেট আসলে অনুরোধ করা হয়, ভেরিয়েবলগুলি কবে ধরা হয়েছিল তা নয়:

int factor = 2;
Func<int, int> multiplier = n => n * factor;
factor = 10;
Console.WriteLine (multiplier (3)); // 30

0

আপনি যদি কোনও ইনলাইন বেনামে পদ্ধতি (সি # 2) বা (পছন্দ) একটি ল্যাম্বডা এক্সপ্রেশন (সি # 3 +) লিখেন তবে একটি আসল পদ্ধতি এখনও তৈরি হচ্ছে। যদি সেই কোডটি একটি বহিরাগত স্কোপ স্থানীয় ভেরিয়েবল ব্যবহার করে - তবে আপনাকে এখনও সেই পরিবর্তনশীলটি কোনওভাবে পদ্ধতিতে পাস করতে হবে।

উদাহরণস্বরূপ এই লিনকটি নিন যেখানে ক্লজ (এটি একটি সাধারণ এক্সটেনশন পদ্ধতি যা ল্যাম্বডা এক্সপ্রেশনটি পাস করে):

var i = 0;
var items = new List<string>
{
    "Hello","World"
};   
var filtered = items.Where(x =>
// this is a predicate, i.e. a Func<T, bool> written as a lambda expression
// which is still a method actually being created for you in compile time 
{
    i++;
    return true;
});

আপনি যদি সেই ল্যাম্বদা এক্সপ্রেশনটিতে i ব্যবহার করতে চান তবে আপনাকে এটি তৈরি পদ্ধতিতে পাস করতে হবে।

সুতরাং প্রথম প্রশ্নটি দেখা দেয়: এটি মান বা রেফারেন্স দ্বারা পাস করা উচিত?

রেফারেন্সের মাধ্যমে পাসটি হ'ল (আমি অনুমান করি) আপনি সেই পরিবর্তনশীলটিতে পড়ার / লেখার অ্যাক্সেস পাওয়ার সাথে সাথে আরও ভাল (এবং এটি সি # যা করে; আমি অনুমান করি যে মাইক্রোসফ্টের দলটি উপকারিতা এবং মতামত ওজন করেছে এবং বাই রেফারেন্সের সাথে চলেছে; জোন স্কিটির মতে ) নিবন্ধ , জাভা বাই-ভ্যালু সহ গেল)।

কিন্তু তারপরে আর একটি প্রশ্ন ওঠে: আমি কোথায় বরাদ্দ করব?

এটি আসলে / প্রাকৃতিকভাবে স্ট্যাকের বরাদ্দ করা উচিত? ঠিক আছে, আপনি যদি এটি স্ট্যাকের জন্য বরাদ্দ করেন এবং রেফারেন্সের মাধ্যমে এটি পাস করেন তবে এমন পরিস্থিতি তৈরি হতে পারে যেখানে এটি নিজের স্ট্যাকের ফ্রেমকে ছাড়িয়ে যায়। এই উদাহরণটি ধরুন:

static void Main(string[] args)
{
    Outlive();
    var list = whereItems.ToList();
    Console.ReadLine();
}

static IEnumerable<string> whereItems;

static void Outlive()
{
    var i = 0;
    var items = new List<string>
    {
        "Hello","World"
    };            
    whereItems = items.Where(x =>
    {
        i++;
        Console.WriteLine(i);
        return true;
    });            
}

ল্যাম্বডা এক্সপ্রেশন (যেখানে ক্লজটিতে) আবার একটি পদ্ধতি তৈরি করে যা একটি আইকে বোঝায়। যদি আমি আউটলাইভের স্ট্যাকের জন্য বরাদ্দ করা হয়, তবে আপনি যখনই আইটেমগুলি গণনা করবেন, আমি উত্পন্ন পদ্ধতিতে ব্যবহৃত আই আউটলাইভের আইটিকে নির্দেশ করব, অর্থাত্ স্ট্যাকের কোনও জায়গায় যা আর অ্যাক্সেসযোগ্য নয়।

ঠিক আছে, তাই আমাদের তখন এটি স্তূপের প্রয়োজন।

সুতরাং সি # সংকলকটি এই ইনলাইন বেনামে / ল্যাম্বডাকে সমর্থন করতে যা করে, " ক্লোজারস " নামে পরিচিত এটি ব্যবহার করে: এটি হিপ নামে একটি ক্লাস তৈরি করে ( বরং খারাপভাবে ) ডিসপ্লেসক্লাসে আই ক্ষেত্রযুক্ত একটি ক্ষেত্র রয়েছে এবং যে ফাংশনটি আসলে ব্যবহার করে এটা।

এর সমতুল্য কিছু (আপনি ILSpy বা ILDASM ব্যবহার করে উত্পন্ন আইএল দেখতে পারেন):

class <>c_DisplayClass1
{
    public int i;

    public bool <GetFunc>b__0()
    {
        this.i++;
        Console.WriteLine(i);
        return true;
    }
}

এটি আপনার স্থানীয় স্কোপে সেই বর্গটি ইনস্ট্যান্ট করে এবং আই বা ল্যাম্বডা এক্সপ্রেশন সম্পর্কিত কোনও কোডকে সেই ক্লোজারের উদাহরণ সহ প্রতিস্থাপন করে। সুতরাং - যে কোনও সময় আপনি আপনার "স্থানীয় স্কোপ" কোডে যেখানে আমি সংজ্ঞায়িত হয়েছিল সেখানে ব্যবহার করছি, আপনি আসলে সেই প্রদর্শনক্লাস উদাহরণ ক্ষেত্রটি ব্যবহার করছেন।

সুতরাং আমি যদি প্রধান পদ্ধতিতে "স্থানীয়" আমি পরিবর্তন করতে পারি, তবে এটি _DisplayClass.i আসলে পরিবর্তন হবে;

অর্থাত

var i = 0;
var items = new List<string>
{
    "Hello","World"
};  
var filtered = items.Where(x =>
{
    i++;
    return true;
});
filtered.ToList(); // will enumerate filtered, i = 2
i = 10;            // i will be overwriten with 10
filtered.ToList(); // will enumerate filtered again, i = 12
Console.WriteLine(i); // should print out 12

এটি 12 মুদ্রণ করবে, যেহেতু "i = 10" অপ্রত্যাশিত ক্ষেত্রটিতে যায় এবং দ্বিতীয় গণনার ঠিক আগে এটি পরিবর্তন করে।

বিষয়টির একটি ভাল উত্স হ'ল এই বার্ট ডি স্মেট বহুবর্ধক মডিউল (নিবন্ধকরণের প্রয়োজন) (এছাড়াও "হোস্টিং" শব্দটির তার ভ্রান্ত ব্যবহারকে উপেক্ষা করুন - তিনি (আমার মনে হয়) তার অর্থ হ'ল স্থানীয় ভেরিয়েবল (যেমন i) উল্লেখ করার জন্য পরিবর্তন করা হয়েছে নতুন ডিসপ্লেক্লাস ফিল্ডে)।


অন্যান্য খবরে, কিছু ভুল ধারণা রয়েছে বলে মনে হচ্ছে যে "ক্লোজারগুলি" লুপগুলির সাথে সম্পর্কিত - কারণ আমি বুঝতে পারি "বন্ধকরণ" লুপ সম্পর্কিত কোনও ধারণা নয় , বরং বেনামে পদ্ধতিতে / ল্যাম্বডা এক্সপ্রেশনগুলি স্থানীয় স্কোপড ভেরিয়েবলগুলির ব্যবহার - যদিও কিছু কৌশল প্রশ্নগুলি এটি প্রদর্শনের জন্য লুপগুলি ব্যবহার করে।


-1

ক্লোজার হ'ল একটি ফাংশন যা কোনও ফাংশনের মধ্যে সংজ্ঞায়িত হয়, এটি এর স্থানীয় ভেরিয়েবলগুলির পাশাপাশি তার পিতামাতাকে অ্যাক্সেস করতে পারে।

public string GetByName(string name)
{
   List<things> theThings = new List<things>();
  return  theThings.Find<things>(t => t.Name == name)[0];
}

সুতরাং অনুসন্ধান পদ্ধতির ভিতরে ফাংশন।

 t => t.Name == name

এর স্কোপ, টি এর মধ্যে ভেরিয়েবলগুলি অ্যাক্সেস করতে পারে এবং তার পিতামাতার স্কোপে থাকা ভেরিয়েবলের নাম। যদিও এটি ডেলিগেট হিসাবে সন্ধানের পদ্ধতি দ্বারা কার্যকর করা হয়, অন্য সুযোগ থেকে সমস্ত একসাথে।


2
বন্ধ একটি ফাংশন নয়, প্রতি সে, এটি ফাংশনগুলির চেয়ে সুযোগ সম্পর্কে কথা বলে আরও সংজ্ঞায়িত হয়। কার্যকারিতা কেবলমাত্র চারপাশ ঘিরে রাখতে সহায়তা করে, যার ফলে কোনও ক্লোজার তৈরি হয়। তবে একটি ক্লোজার বলা একটি ফাংশন প্রযুক্তিগতভাবে সঠিক নয়। নিতপিকের জন্য দুঃখিত। :)
জেসন বুটিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.