রোজলিন কোড সংকলন করতে ব্যর্থ


95

আমি আমার প্রকল্পটি ভিএস ২০১৩ থেকে ভিএস ২০১৫ এ স্থানান্তরিত করার পরে প্রকল্প আর তৈরি করে না। নিম্নলিখিত লিনকিউ বিবৃতিতে একটি সংকলন ত্রুটি ঘটে:

static void Main(string[] args)
{
    decimal a, b;
    IEnumerable<dynamic> array = new string[] { "10", "20", "30" };
    var result = (from v in array
                  where decimal.TryParse(v, out a) && decimal.TryParse("15", out b) && a <= b // Error here
                  orderby decimal.Parse(v)
                  select v).ToArray();
}

সংকলক একটি ত্রুটি প্রদান করে:

ত্রুটি CS0165 অ-স্বাক্ষরিত স্থানীয় ভেরিয়েবল 'বি' ব্যবহার

এই সমস্যাটির কারণ কী? একটি সংকলক সেটিংসের মাধ্যমে এটি ঠিক করা সম্ভব?


11
@ বাইনারিওরিয়ার: কেন? এটি কেবলমাত্র প্যারামিটারের bমাধ্যমে নির্ধারণের পরে ব্যবহার করে out
জন স্কিটে

4
ভিএস 2015 ডকুমেন্টেশন বলছে "যদিও আউট আর্গুমেন্ট হিসাবে ভেরিয়েবলগুলি পাস হয়ে যাওয়ার আগে আরম্ভ করার দরকার নেই, তথাকথিত পদ্ধতিটি পদ্ধতিটি ফিরে আসার আগে একটি মান নির্ধারণ করা প্রয়োজন" " সুতরাং এটি কোনও বাগের মতো দেখতে হ্যাঁ, এটি চেষ্টা করে পার্সেস দিয়ে আরম্ভ করার গ্যারান্টিযুক্ত।
রুপ

4
ত্রুটি নির্বিশেষে, এই কোডটি outআর্গুমেন্ট সম্পর্কে খারাপ যাবতীয় উদাহরণ দিয়েছিল । এটি কি TryParseআবার আসার যোগ্য মান (বা সমমান) ফেরত দেবে?
কনরাড রুডল্ফ

4
@KonradRudolph where (a = decimal.TryParse(v)).HasValue && (b = decimal.TryParse(v)).HasValue && a <= bদেখায় অনেক ভাল
Rawling

4
শুধু লক্ষণীয়, আপনি এটিকে সহজ করতে পারেন decimal a, b; var q = decimal.TryParse((dynamic)"10", out a) && decimal.TryParse("15", out b) && a <= b;। আমি এটি উত্থাপনে একটি রোজলিন বাগ খুলেছি
রোলিং

উত্তর:


112

এই সমস্যাটির কারণ কী?

আমার কাছে একটি সংকলক বাগের মতো দেখাচ্ছে। কমপক্ষে, এটা করেছে। যদিও decimal.TryParse(v, out a)এবং decimal.TryParse(v, out b)এক্সপ্রেশন পরিবর্তনশীল মূল্যায়ন করা হয়, আমি আশা কম্পাইলার এখনো বুঝতে যে সময় এটি ছুঁয়েছে দ্বারা a <= bউভয় aএবং bস্পষ্টভাবে নির্ধারিত হয়। এমনকি ডাইনামিক টাইপিংয়ের সাথে আপনি যে অদ্ভুততা অর্জন করতে পারেন, তার সাথে আমি a <= bউভয় TryParseকলকে মূল্যায়ন করার পরে কেবল মূল্যায়ন করার আশা করতাম ।

তবে, এটি প্রমাণিত হয়েছে যে অপারেটর এবং রূপান্তরিত কৌতূহলের মাধ্যমে, এমন একটি ভাব প্রকাশ করা সম্পূর্ণভাবে সম্ভব A && B && Cযা মূল্যায়ন করে Aএবং Cনা B- যদি আপনি যথেষ্ট চালাকি করেন। নীল গিটার্নের বুদ্ধিমান উদাহরণের জন্য রোজলিন বাগ প্রতিবেদনটি দেখুন ।

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

এটি কি সংকলক সেটিংসের মাধ্যমে ঠিক করা সম্ভব?

না, তবে এমন বিকল্প রয়েছে যা ত্রুটি এড়ায়।

প্রথমত, আপনি এটিকে গতিশীল হতে বাধা দিতে পারেন - আপনি যদি জানেন যে আপনি কেবল কখনও স্ট্রিং ব্যবহার করেন তবে আপনি পরিসীমা পরিবর্তনশীলকে এক ধরণের (অর্থাত ) ব্যবহার করতে IEnumerable<string> বা দিতে পারেন । এটি আমার পছন্দসই বিকল্প হবে।vstringfrom string v in array

আপনার যদি সত্যিই এটিকে গতিশীল রাখার প্রয়োজন হয় তবে এটিকে bশুরু করার জন্য কেবল একটি মান দিন:

decimal a, b = 0m;

এটি কোনও ক্ষতি করবে না - আমরা জানি যে প্রকৃতপক্ষে আপনার গতিশীল মূল্যায়ন কোনও পাগল করবে না, তাই আপনি bপ্রাথমিক মানটিকে অপ্রাসঙ্গিক করে তোলার আগে আপনি কোনও মান নির্ধারণের কাজ শেষ করবেন ।

অতিরিক্তভাবে, দেখে মনে হচ্ছে যে বন্ধনী যুক্ত করাও খুব কার্যকর:

where decimal.TryParse(v, out a) && (decimal.TryParse("15", out b) && a <= b)

এটি সেই পয়েন্টে পরিবর্তন করে যেখানে ওভারলোডের বিভিন্ন ধরণের সমাধানের সূত্রপাত ঘটে এবং সংকলককে খুশি করে।

নেই এক সমস্যা এখনও অবশিষ্ট - সঙ্গে নির্দিষ্ট নিয়োগ উপর বৈশিষ্ট এর বিধিগুলি &&অপারেটর প্রয়োজন অবস্থায় ব্যাখ্যা করা যে, তারা শুধুমাত্র যখন প্রযোজ্য &&অপারেটর দুই সঙ্গে তার "নিয়মিত" বাস্তবায়ন ব্যবহৃত হচ্ছে booloperands। আমি এটি পরবর্তী ইসিএমএ স্ট্যান্ডার্ডের জন্য স্থির করে নেওয়ার চেষ্টা করব।


হ্যাঁ! IEnumerable<string>ব্র্যাকেট প্রয়োগ বা যুক্ত করা আমার পক্ষে কাজ করেছিল। এখন সংকলক ত্রুটি ছাড়াই বিল্ড।
ramil89

4
ব্যবহারের decimal a, b = 0m;ফলে ত্রুটি মুছে ফেলা হতে পারে তবে তারপরে a <= bসর্বদা ব্যবহার করা হবে 0m, যেহেতু আউট মানটি এখনও গণনা করা হয়নি।
পা বাল্টজারসেন

12
@ পাবাল্টজার্সেন: আপনার এমন ভাবনা কিসের সৃষ্টি করে? এটি সর্বদা তুলনার আগে নির্ধারিত হবে - এটি কেবল কারণ যে কোনও কারণে (একটি বাগ, মূলত) সংকলক এটি প্রমাণ করতে পারে না।
জন স্কিটে

4
পার্শ্ব প্রতিক্রিয়া ছাড়া পার্সিং পদ্ধতি থাকা অর্থাৎ। decimal? TryParseDecimal(string txt)একটি সমাধানও হতে পারে
zahir

4
আমি ভাবছি যদি এটি অলস সূচনা হয়; এটি মনে করে "যদি প্রথমটি সত্য হয় তবে আমার দ্বিতীয়টির মূল্যায়ন করার দরকার নেই যার অর্থ bসম্ভবত অর্পণ করা হবে না"; আমি জানি যে এটি অবৈধ যুক্তিযুক্ত তবে এটি ব্যাখ্যা করে যে বন্ধনীগুলি কেন এটি সংশোধন করে ...
durron597

21

এটি রোজিলিন সংকলকটিতে বাগ বা কমপক্ষে রিগ্রেশন হিসাবে উপস্থিত হতে পারে। এটি চিহ্নিত করার জন্য নিম্নলিখিত বাগটি দায়ের করা হয়েছে:

https://github.com/dotnet/roslyn/issues/4509

ইতিমধ্যে, জনের দুর্দান্ত উত্তরের বেশ কয়েকটি কাজ রয়েছে।


এছাড়াও এই বাগটি নোট করে যে এটি এখনই লিনিক্যু ...
রোলিং

16

যেহেতু বাগের প্রতিবেদনে আমি এত কঠোরভাবে ছড়িয়ে পড়েছি, তাই আমি নিজেই এটি ব্যাখ্যা করার চেষ্টা করব।


কল্পনাটি Tএমন কিছু ব্যবহারকারী-সংজ্ঞায়িত টাইপ যা অন্তর্ভুক্ত castালাইয়ের সাথে শুরু হয় এবং এর boolমধ্য দিয়ে বিকল্প হয় । সংকলক যতদূর জানে, প্রথম প্রথম যুক্তিটি সেই ধরণের মূল্যায়ন করতে পারে, তাই এটি হতাশাব্যঞ্জক হতে হবে।falsetruefalsedynamic&&

যদি, তাহলে এটি কোডটি সংকলন করতে দেয়, এটি ঘটতে পারে:

  • ডায়নামিক বাইন্ডার যখন প্রথমটি মূল্যায়ন &&করে তখন তা নিম্নলিখিতটি করে:
    • প্রথম যুক্তি মূল্যায়ন করুন
    • এটি একটি T- স্পষ্টতই এটিতে castালাই bool
    • ওহ, এটি falseতাই আমাদের দ্বিতীয় যুক্তির মূল্যায়ন করার দরকার নেই।
    • ফলাফল তৈরি করুন &&প্রথম যুক্তি হিসাবে মূল্যায়ন । (না, না false, কোনও কারণে।)
  • যখন ডায়নামিক বাইন্ডার দ্বিতীয়টি মূল্যায়ন করে &&, তা নিম্নলিখিতটি করে:
    • প্রথম যুক্তি মূল্যায়ন করুন।
    • এটা একটা T- স্পষ্টতই এটিতে castালাই bool
    • ওহ, এটি trueতাই দ্বিতীয় যুক্তিটি মূল্যায়ন করুন।
    • ... ওহ কর্কট, bবরাদ্দ করা হয়নি।

স্পষ্ট ভাষায়, সংক্ষেপে, এখানে বিশেষ "সুনির্দিষ্ট অ্যাসাইনমেন্ট" বিধি রয়েছে যা চলককে "স্পষ্টরূপে নির্ধারিত" বা "অবশ্যই নির্ধারিত নয়" বলা হয় তা নয়, এটি যদি "পরে অবশ্যই নির্ধারিত হয়" false বিবরণের " বা "অবশ্যই" trueবিবৃতি পরে নির্ধারিত "।

এগুলি বিদ্যমান যাতে ডিল করার সময় &&এবং ||(এবং !এবং ??এবং)?: ) কম্পাইলার পরীক্ষা করতে পারেন কিনা ভেরিয়েবল একটি জটিল বুলিয়ান অভিব্যক্তি নির্দিষ্ট শাখায় নিয়োগ করা হতে পারে।

তবে এগুলি কেবল তখনই কাজ করে যখন এক্সপ্রেশনগুলির ধরণগুলি বুলিয়ান থাকে । যখন অভিব্যক্তির অংশ হয় dynamic(বা একটি নন-বুলিয়ান স্ট্যাটিক টাইপ) আমরা আর নির্ভরযোগ্যভাবে বলতে পারি না যে অভিব্যক্তিটি trueবা false- পরের বার আমরা boolকোন শাখা নেওয়ার সিদ্ধান্ত নেওয়ার জন্য এটি নিক্ষেপ করলাম তখন এটির মন পরিবর্তন হতে পারে।


আপডেট: এটি এখন সমাধান হয়েছে এবং নথিভুক্ত করা হয়েছে :

গতিশীল অভিব্যক্তিগুলির জন্য পূর্ববর্তী সংকলকগণ দ্বারা প্রয়োগ করা সুনির্দিষ্ট কার্যবিধির বিধিগুলি এমন কিছু কোডের মঞ্জুরি দেয় যার ফলে ভেরিয়েবলগুলি পড়তে পারে যা অবশ্যই দেওয়া হয়নি assigned এর একটি প্রতিবেদনের জন্য https://github.com/dotnet/roslyn/issues/4509 দেখুন ।

...

এই সম্ভাবনার কারণে সংকলক অবশ্যই এই প্রোগ্রামটি সংকলন করার অনুমতি দেবে না যদি ভাল এর কোনও প্রাথমিক মান না থাকে। সংকলকের পূর্ববর্তী সংস্করণগুলি (ভিএস ২০১৫ এর পূর্বে) এই প্রোগ্রামটি সংকলন করার অনুমতি দিয়েছে এমনকি ভালের কোনও প্রাথমিক মান না থাকলেও। রোজলিন সম্ভবত একটি সম্ভাবনাময় অস্বীকৃত ভেরিয়েবলটি পড়ার এই প্রয়াসটি নির্ধারণ করে।


4
আমার অন্যান্য মেশিনে ভিএস ২০১৩ ব্যবহার করে, আমি এটি ব্যবহার করে আনইনড মেমরিটি পড়তে আসলে পরিচালনা করেছি। এটি খুব উত্তেজনাপূর্ণ নয় :(
রোলিং

আপনি সাধারণ প্রতিনিধি সহ অবিচ্ছিন্ন ভেরিয়েবলগুলি পড়তে পারেন। এমন একটি প্রতিনিধি তৈরি করুন যা outএকটি পদ্ধতিতে আসে ref। এটি আনন্দের সাথে এটি করবে এবং মান পরিবর্তন না করে এটি ভেরিয়েবলকে নির্ধারিত করবে।
IllidanS4 22.315 এ মনিকে

কৌতূহলের বাইরে আমি সেই স্নিপেটটি সি # ভি 4 দিয়ে পরীক্ষা করেছি। কৌতূহলের বাইরে, যদিও - সংকলক কীভাবে অপারেটরটি ব্যবহার করার সিদ্ধান্ত নেয় false/ trueঅন্তর্নিহিত কাস্ট অপারেটরের বিপরীতে? স্থানীয়ভাবে, এটি implicit operator boolপ্রথম যুক্তিটি কল করবে , তারপরে দ্বিতীয় অপারেন্ডকে ডাকবে operator false, প্রথম অপারেন্ডকে কল করবে, তারপরে আবারimplicit operator bool প্রথম অপারেন্ডে কল করবে । এটি আমার কাছে কোনও অর্থবোধ করে না, প্রথম অপারেন্ডটি মূলত একবারে বুলিয়নে ফোটানো উচিত, না?
রব

@ রব এটি কি dynamic, শৃঙ্খলিত - &&কেস? আমি এটি মূলত যেতে দেখেছি (1) প্রথম যুক্তির মূল্যায়ন করুন (২) আমি শর্ট সার্কিট করতে পারি কিনা তা দেখার জন্য অন্তর্নিহিত কাস্ট ব্যবহার করুন (3) আমি পারব না, সুতরাং দ্বিতীয় যুক্তিটি খালাস করুন (4) এখন আমি উভয় প্রকারকেই জানি, আমি সেরাটি দেখতে পাবে প্রথম যুক্তিতে &&একটি ব্যবহারকারী-সংজ্ঞায়িত &(5) কল অপারেটর falseআমি শর্ট সার্কিট করতে পারি কিনা তা দেখতে (6) আমি (কারণ falseএবং implicit boolঅসমত) পারি, তাই ফলাফলটি প্রথম যুক্তি ... এবং তারপরে পরবর্তী &&, (7) আমি শর্ট সার্কিট করতে পারি কিনা তা দেখতে নিখুঁত কাস্ট ব্যবহার করুন (আবার)।
রোলিং

@ IllidanS4 আকর্ষণীয় মনে হলেও এটি কীভাবে করব তা আমি খুঁজে পাইনি। আপনি আমাকে একটি স্নিপেট দিতে পারেন?
রোলিং

15

এটি একটি বাগ না। এই ফর্মটির গতিশীল অভিব্যক্তি কীভাবে এইরকম পরিবর্তনশীলকে নিযুক্ত না করতে পারে তার উদাহরণের জন্য https://github.com/dotnet/roslyn/issues/4509#issuecomment-130872713 দেখুন ।


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