পরিবর্তিত সমাপ্তিতে অ্যাক্সেস


316
string [] files = new string[2];
files[0] = "ThinkFarAhead.Example.Settings.Configuration_Local.xml";
files[1] = "ThinkFarAhead.Example.Settings.Configuration_Global.xml";

//Resharper complains this is an "access to modified closure"
for (int i = 0; i < files.Length; i++ )
{
    // Resharper disable AccessToModifiedClosure
    if(Array.Exists(Assembly.GetExecutingAssembly().GetManifestResourceNames(),
    delegate(string name) { return name.Equals(files[i]); }))
         return Assembly.GetExecutingAssembly().GetManifestResourceStream(files[i]);
    // ReSharper restore AccessToModifiedClosure
}

উপরেরগুলি ঠিকঠাক কাজ করছে বলে মনে হচ্ছে যদিও রিসার্পার অভিযোগ করেছেন যে এটি "পরিবর্তিত বন্ধের অ্যাক্সেস"। কেউ কি এ বিষয়ে আলোকপাত করতে পারে?

(এই বিষয় এখানে অবিরত )


6
লিঙ্কটি বাইরে রয়েছে, তবে আমি এটি ওয়েবআর্কাইভে পেয়েছি: web.archive.org/web/20150326104221/http://www.jarloo.com/…
এরিক উ

উত্তর:


314

এই ক্ষেত্রে, এটি ঠিক আছে, যেহেতু আপনি আসলে লুপের মধ্যে ডেলিগেটটি কার্যকর করছেন exec

আপনি প্রতিনিধি সংরক্ষণ এবং এটি পরে ব্যবহার ছিল, কিন্তু, আপনি খুঁজে পেতে চাই যে প্রতিনিধিদের সব ব্যতিক্রম নিক্ষেপ করা হবে যখন ফাইলগুলি অ্যাক্সেস করার চেষ্টা [আমি] - তারা আটক করছি পরিবর্তনশীল i প্রতিনিধিদের সময় বরং তার মানের চেয়ে সৃষ্টি।

সংক্ষেপে, এটি একটি সম্ভাব্য ফাঁদ হিসাবে সচেতন হওয়ার কিছু , তবে এই ক্ষেত্রে এটি আপনার ক্ষতি করে না।

আরও জটিল উদাহরণের জন্য এই পৃষ্ঠার নীচের অংশটি দেখুন যেখানে ফলাফলগুলি বিপরীতমুখী।


29

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

private sealed class Closure
{
    public string[] files;
    public int i;

    public bool YourAnonymousMethod(string name)
    {
        return name.Equals(this.files[this.i]);
    }
}

উপরে উল্লিখিত হিসাবে, আপনার ফাংশনটি কাজ করে কারণ পূর্বাভাসগুলি সৃষ্টির পরপরই ডাকা হয়। সংকলক এর মতো কিছু তৈরি করবে:

private string Works()
{
    var closure = new Closure();

    closure.files = new string[3];
    closure.files[0] = "notfoo";
    closure.files[1] = "bar";
    closure.files[2] = "notbaz";

    var arrayToSearch = new string[] { "foo", "bar", "baz" };

    //this works, because the predicates are being executed during the loop
    for (closure.i = 0; closure.i < closure.files.Length; closure.i++)
    {
        if (Array.Exists(arrayToSearch, closure.YourAnonymousMethod))
            return closure.files[closure.i];
    }

    return null;
}

অন্যদিকে, আপনি যদি সংরক্ষণ এবং তারপরে ভবিষ্যদ্বাণীগুলি অবলম্বন করতে চান তবে আপনি দেখতে পাবেন যে পূর্বাভাসকারীদের প্রতি একক কল সত্যই একই পদ্ধতিটিকে ক্লোজার ক্লাসের একই উদাহরণে কল করবে এবং সেইজন্য একই মানটি ব্যবহার করবে আমি।


4

"ফাইল" হ'ল একটি বন্দী বহিরাগত পরিবর্তনশীল কারণ এটি বেনাম প্রতিনিধি ফাংশন দ্বারা ক্যাপচার করা হয়েছে। এর আজীবন বেনামে প্রতিনিধি ফাংশন দ্বারা প্রসারিত।

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

এমএসডিএন-এ আউটার ভেরিয়েবলগুলি

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.