কেন আমি পিতামাতার স্কোপগুলিতে ভেরিয়েবল হিসাবে একই নামের সাথে একটি শিশু ভেরিয়েবল ঘোষণা করতে পারি?


23

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

var x = 1;
Action<int> myAction = (x) => { Console.WriteLine(x); };

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

কেন এই কোড কাজ করে? আমি ভিজুয়াল স্টুডিও 2019 এর সাথে সি # 8 ব্যবহার করছি।


1
সংকলক দ্বারা উত্পাদিত ক্লাসের একটি পদ্ধতিতে ল্যাম্বডা সরানো হয়েছে এবং এই xপদ্ধতিতে পুরো পরামিতিটি সুযোগের বাইরে চলে যায়। উদাহরণের জন্য শার্পল্যাব দেখুন ।
লাসে ভি কার্লসেন

6
এটি সম্ভবত এখানে লক্ষণীয় যে C # 7.3 টার্গেট করার সময় এটি সংকলন করবে না, সুতরাং এটি সি # 8 এর সাথে একচেটিয়া বলে মনে হচ্ছে।
জনাথন চেজ

লিঙ্কযুক্ত প্রশ্নের কোডটি শর্টল্যাবে জরিমানা সংকলন করে । এটি সাম্প্রতিক পরিবর্তন হতে পারে।
লাসে ভি কার্লসেন

2
: একটি প্রতারিত (একটি উত্তর ছাড়া) পাওয়া stackoverflow.com/questions/58639477/...
bolov

উত্তর:


26

কেন এই কোড কাজ করে? আমি ভিজুয়াল স্টুডিও 2019 এর সাথে সি # 8 ব্যবহার করছি।

আপনি আপনার নিজের প্রশ্নের উত্তর দিয়েছেন! কারণ আপনি সি # 8 ব্যবহার করছেন।

সি # 1 থেকে 7 এর নিয়মটি ছিল: একটি সাধারণ নাম একই স্থানীয় ক্ষেত্রের দুটি ভিন্ন জিনিস বোঝাতে ব্যবহার করা যায় না। (প্রকৃত নিয়ম তার চেয়ে কিছুটা জটিল ছিল তবে কীভাবে ক্লান্তিকর তা বর্ণনা করে; বিশদ বিবরণের জন্য সি # স্পেসিফিকেশন দেখুন))

এই নিয়মের উদ্দেশ্যটি হ'ল আপনি নিজের উদাহরণে যে ধরণের পরিস্থিতি সম্পর্কে কথা বলছেন তা প্রতিরোধ করা, যেখানে স্থানীয় অর্থটি সম্পর্কে বিভ্রান্ত হওয়া খুব সহজ হয়ে যায়। বিশেষতঃ এই বিধিটি এমন বিভ্রান্তি রোধের জন্য তৈরি করা হয়েছিল:

class C 
{
  int x;
  void M()
  {
    x = 123;
    if (whatever)
    {
      int x = 356;
      ...

আর এখন আমরা একটি পরিস্থিতির শরীরে যেখানে আছে M, xমানে উভয় this.xএবং স্থানীয় x

যদিও উদ্দেশ্যপ্রণোদিত, এই বিধি নিয়ে বেশ কয়েকটি সমস্যা ছিল:

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

আমি এটিকে সাজানোর জন্য রোজলাইন পুনরায় লেখায় একটি প্রচেষ্টা করেছি; আমি কিছু নতুন ত্রুটি বার্তা যুক্ত করেছি এবং পুরানোগুলি ত্রুটিটি কোথায় রিপোর্ট করা হয়েছে সে সম্পর্কে সামঞ্জস্য রেখেছি। তবে এই প্রচেষ্টাটি খুব অল্প, খুব দেরিতে হয়েছিল।

সি # টি টি সি # 8 এর জন্য সিদ্ধান্ত নিয়েছিল যে পুরো নিয়মটি প্রতিরোধের চেয়ে আরও বিভ্রান্তি সৃষ্টি করছে এবং ভাষা থেকে এই নিয়ম অবসর নেওয়া হয়েছিল। (অবসর কখন ঘটেছিল তা নির্ধারণ করার জন্য ধন্যবাদ জোনাথন চেজ।)

আপনি যদি এই সমস্যার ইতিহাস জানতে আগ্রহী হন এবং আমি কীভাবে এটি ঠিক করার চেষ্টা করেছি, আমি এই সম্পর্কে নিবন্ধগুলি দেখুন:

https://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/

https://ericlippert.com/2009/11/05/simple-names-are-not-so-simple-part-two/

https://ericlippert.com/2014/09/25/confusing-errors-for-a-confusing-feature-part-one/

https://ericlippert.com/2014/09/29/confusing-errors-for-a-confusing-feature-part-two/

https://ericlippert.com/2014/10/03/confusing-errors-for-a-confusing-feature-part-three/

তৃতীয় অংশের শেষে আমি উল্লেখ করেছি যে এই বৈশিষ্ট্য এবং "রঙিন রঙ" বৈশিষ্ট্যের মধ্যে একটি মিথস্ক্রিয়াও ছিল - এটি এমন বৈশিষ্ট্য যা এতে অনুমতি দেয়:

class C
{
  Color Color { get; set; }
  void M()
  {
    Color = Color.Red;
  }
}

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

এই দুটি নিয়মের মধ্যে সমস্ত অদ্ভুত মিথস্ক্রিয়া বর্ণনা করে আমি আর্টিকেলটি কখনই লিখিনি, এবং এখনই এটি করা কিছুটা অর্থহীন হবে!


প্রশ্নের কোডটি সি # 6, 7, 7.1, 7.2, এবং 7.3 এর জন্য সংকলন করতে ব্যর্থ হয়েছে, "CS0136: 'x' নামের স্থানীয় বা প্যারামিটারটি এই সুযোগে ঘোষণা করা যায় না কারণ এই নামটি ..."। দেখে মনে হচ্ছে নিয়মটি এখনও সি # 8 অবধি কার্যকর হয়েছে
জোনাথন চেজ

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