সি # এবং জাভা এর টেরিনারি অপারেটরের মধ্যে পার্থক্য (? :)


94

আমি সি # নবাগত এবং আমি কেবল একটি সমস্যার মুখোমুখি হয়েছি। টেরিনারি অপারেটর ( ? :) এর সাথে ডিল করার সময় সি # এবং জাভার মধ্যে পার্থক্য রয়েছে ।

নিম্নলিখিত কোড বিভাগে, 4 র্থ লাইনটি কেন কাজ করে না? সংকলক এর একটি ত্রুটি বার্তা দেখায় there is no implicit conversion between 'int' and 'string'। 5 তম লাইনটি তেমন কাজ করে না। দুটি Listগুলিই বস্তু, তাই না?

int two = 2;
double six = 6.0;
Write(two > six ? two : six); //param: double
Write(two > six ? two : "6"); //param: not object
Write(two > six ? new List<int>() : new List<string>()); //param: not object

তবে একই কোড জাভাতে কাজ করে:

int two = 2;
double six = 6.0;
System.out.println(two > six ? two : six); //param: double
System.out.println(two > six ? two : "6"); //param: Object
System.out.println(two > six ? new ArrayList<Integer>()
                   : new ArrayList<String>()); //param: Object

সি # তে কোন ভাষার বৈশিষ্ট্য অনুপস্থিত? যদি কোনও হয় তবে এটি যুক্ত করা হয় না কেন?


4
অনুযায়ী msdn.microsoft.com/en-us/library/ty67wk28.aspx "হয় first_expression এবং second_expression ধরণ একই হতে হবে, অথবা একটি অন্তর্নিহিত রূপান্তর এক ধরনের থেকে অন্য থাকা আবশ্যক।"
ডিম

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

4
@ blackr1234 কারণ একটি intকোনও বস্তু নয়। এটি একটি আদিম।
কোড-শিক্ষানবিস

4
@ কোড-শিক্ষানবিস হ্যাঁ এগুলি আসলেই খুব আলাদা - সি # এর রানটাইম পুনঃনির্ধারণ রয়েছে, সুতরাং তালিকাটি সম্পর্কিত নয় of ওহ, এবং আপনি কিছুটা সম্পর্কের স্তর প্রবর্তন করতে চাইলে মিশ্রের মধ্যে জেনেরিক ইন্টারফেস কোভারিয়েন্স / বৈপরীত্যও ফেলে দিতে পারেন;)
লুকাস ট্রাজেনউইস্কি

4
ওপি সুবিধার জন্য: জাভা উপায়ে টাইপ ইরেজিওর যে ArrayList<String>এবং ArrayList<Integer>পরিণত শুধু ArrayListবাইটকোড হবে। এর অর্থ এটি রান-টাইমে হুবহু একই ধরণের বলে মনে হয়। দৃশ্যত সি # এ তারা বিভিন্ন ধরণের।
কোড-শিক্ষানবিস

উত্তর:


106

মাধ্যমে দেখার জন্যে সি # 5 ভাষা নির্দিষ্টকরণ অধ্যায় 7.14: শর্তসাপেক্ষ অপারেটর আমরা নিম্নলিখিত দেখতে পারেন:

  • যদি x এর টাইপ এক্স এবং y এর Y টাইপ থাকে then

    • যদি কোনও অন্তর্নিহিত রূপান্তর (§6.1) X থেকে Y তে উপস্থিত থাকে তবে Y থেকে X তে থাকে না, তবে Y শর্তসাপেক্ষ প্রকাশের ধরণ।

    • যদি কোনও অন্তর্নিহিত রূপান্তর (§6.1) Y থেকে X এ উপস্থিত থাকে তবে X থেকে Y তে নয়, তবে এক্স শর্তাধীন ভাবের ধরণ।

    • অন্যথায়, কোনও প্রকাশের ধরণ নির্ধারণ করা যায় না এবং একটি সংকলন-সময় ত্রুটি ঘটে

অন্য কথায়: এটি x এবং y কে অন্যে রূপান্তর করতে পারে কিনা তা অনুসন্ধান করার চেষ্টা করে এবং যদি না হয় তবে সংকলন ত্রুটি ঘটে। আমাদের ক্ষেত্রে intএবং stringকোনও সুস্পষ্ট বা অন্তর্নিহিত রূপান্তর নেই তাই এটি সংকলন করবে না।

এটি জাভা 7 ভাষা নির্দিষ্টকরণ বিভাগ 15.25 এর সাথে বিপরীতে করুন : শর্তাধীন অপারেটর :

  • দ্বিতীয় এবং তৃতীয় অপারেন্ডগুলির যদি একই ধরণের থাকে (যা নাল টাইপ হতে পারে), তবে এটি শর্তসাপেক্ষ প্রকাশের ধরণ। ( না )
  • যদি দ্বিতীয় এবং তৃতীয় অপারেশনগুলির মধ্যে একটি আদিম প্রকার টি হয়, এবং অন্যটির ধরণটি বক্সিং রূপান্তর (§5.1.7) টি-তে প্রয়োগ করার ফলস্বরূপ হয়, তবে শর্তসাপেক্ষ প্রকাশের ধরণটি টি। ( NO ) নয়
  • যদি দ্বিতীয় এবং তৃতীয় অপারেন্ডগুলির মধ্যে একটি নাল টাইপের হয় এবং অন্যটির প্রকারটি একটি রেফারেন্স টাইপ হয়, তবে শর্তাধীন এক্সপ্রেশনটির ধরণটি সেই রেফারেন্স টাইপ। ( না )
  • অন্যথায়, যদি দ্বিতীয় এবং তৃতীয় অপারেন্ডসের সংখ্যার সাথে রূপান্তরযোগ্য (§5.1.8) টাইপ থাকে তবে কয়েকটি ক্ষেত্রে রয়েছে: ( কোনও )
  • অন্যথায়, দ্বিতীয় এবং তৃতীয় অপারেশনগুলি যথাক্রমে এস 1 এবং এস 2 ধরণের। এস 1-তে বক্সিং রূপান্তর প্রয়োগ করে ফলাফলটি টি 1 এর মতো হয়ে উঠুক এবং এস 2-তে বক্সিং রূপান্তর প্রয়োগের ফলে টি 2 কে এমন ধরণের সুযোগ দিন।
    শর্তসাপেক্ষ প্রকাশের প্রকারটি হ'ল ক্যাপচার রূপান্তর (.15.1.10) প্রয়োগ করে (টি 1, টি 2) (.115.12.2.7) .7 ( হ্যাঁ )

এবং, বিভাগ 15.12.2.7 এ খুঁজছেন প্রকার আর্গুমেন্ট ACTUAL টি যুক্তি উপর নির্ভর করে inferring আমরা এটিকে সাধারণ পূর্বপুরুষ যে কল যা এটি দিয়ে জমি জন্য ব্যবহৃত টাইপ হিসেবে পরিবেশন করা হবে খোঁজ করে দেখতে পারেন ObjectObject হয় একটি গ্রহণযোগ্য যুক্তি তাই কল কাজ করবে।


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

4
আপনি স্পেসিফিকেশন থেকে সরাসরি উদ্ধৃত করার পরে অবশ্যই এটি এখনও সবচেয়ে সম্পূর্ণ উত্তর।
কোড-শিক্ষানবিস

এটি আসলে জাভা 5 দিয়েই পরিবর্তিত হয়েছিল (আমার ধারণা, সম্ভবত 6 টি ছিল)। এর আগে জাভার সি # এর মতোই আচরণ ছিল। এনামগুলি যেভাবে প্রয়োগ করা হয় তার কারণে এটি সম্ভবত সি # এর চেয়ে জাভাতে আরও বিস্ময় প্রকাশ করেছে যদিও এটি পাশাপাশি একটি ভাল পরিবর্তন।
ভু

@ ভু: এফওয়াইআই, জাভা ৫ এবং জাভা এর একই স্পেস সংস্করণ রয়েছে ( জাভা ল্যাঙ্গুয়েজ স্পেসিফিকেশন , তৃতীয় সংস্করণ), সুতরাং এটি অবশ্যই জাভা
in-তে

86

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

টেরিনারি অপারেটরের ক্ষেত্রে সি # আরও সাধারণ ধরণের ইনট এবং স্ট্রিং বেছে নেওয়ার চেষ্টা করে তবে দুটিও সাধারণ প্রকার নয়। প্রথমে পছন্দ নয় এমন কোনও ধরণের বাছাইয়ের পরিবর্তে অবজেক্টের মতো, সি # সিদ্ধান্ত নিয়েছে যে কোনও ধরণের অনুমান করা যাবে না।

আমি আরও লক্ষ করি যে এটি সি # এর আরেকটি ডিজাইনের নীতি অনুসরণ করছে: যদি কিছু ভুল মনে হয় তবে বিকাশকারীকে বলুন। ভাষাটি বলে না যে "আপনি কী বোঝাতে চেয়েছিলেন তা অনুমান করতে যাচ্ছি এবং যদি পারতে পারি তবে তা বিচলিত করব"। ভাষাটি বলে "আমার মনে হয় আপনি এখানে কিছু বিভ্রান্তিকর লিখেছেন, এবং আমি আপনাকে সে সম্পর্কে বলব।"

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


6
হঠাৎ করে কেন সাম্প্রদায়িকতা / বৈপরীত্যের আগ্রহ, তা নিয়ে আমি প্রথম অনুচ্ছেদে পেরিয়ে গেলাম, তারপরে আমি দ্বিতীয় অনুচ্ছেদে আরও সম্মত হতে শুরু করেছি, তবে আমি দেখেছি উত্তরটি কে লিখেছিল ... তাড়াতাড়ি অনুমান করা উচিত ছিল। আপনি কি কখনও লক্ষ্য করেছেন যে আপনি উদাহরণ হিসাবে 'জিরাফ' কতটা ব্যবহার করেন ? আপনাকে অবশ্যই জিরাফস পছন্দ করবে।
ফারাপ

21
জিরাফ দুর্দান্ত!
এরিক লিপার্ট

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

7
@ ফারাপ: অর্থাৎ, প্রশ্নটি সাধারণত এমন কিছু হয় যে "গ্রাহক চালানের সরবরাহকারী কারখানার তালিকা কেন চালান সরবরাহকারী কারখানার তালিকা হিসাবে ব্যবহার করা যাবে না?" এবং আপনার অন্তর্নিহিতটি "হ্যাঁ, সেগুলি মূলত একই জিনিস" বলে, তবে আপনি যখন "জিরাফ পূর্ণ একটি ঘর কেন স্তন্যপায়ী প্রাণীদের ঘর হিসাবে ব্যবহার করতে পারবেন না?" তারপরে এটি বলার মতো একটি স্বজ্ঞাত উপমা হয়ে যায় "কারণ স্তন্যপায়ী প্রাণীদের দ্বারা পূর্ণ ঘরে একটি বাঘ থাকতে পারে, জিরাফ পূর্ণ ঘরে একটি ঘর থাকতে পারে না"।
এরিক লিপার্ট

6
@ এরিক আমি প্রথমে এই সমস্যায় পড়েছিলাম int? b = (a != 0 ? a : (int?) null)। এর রয়েছে এই প্রশ্নের , পাশ সব লিঙ্ক প্রশ্ন করেন। আপনি যদি লিঙ্কগুলি অনুসরণ করে চালিয়ে যান তবে বেশ কয়েকটি আছে। তুলনায়, আমি কখনও শুনিনি যে জাভা এটির মতো করে কোনও বাস্তব-জগতে জড়িয়ে পড়ে।
ব্লুরাজা - ড্যানি প্লেফুঘুফুট

24

জেনেরিক অংশ সম্পর্কে:

two > six ? new List<int>() : new List<string>()

সি # তে, সংকলক ডান হাতের এক্সপ্রেশন অংশগুলিকে কিছু সাধারণ ধরণের রূপান্তরিত করার চেষ্টা করে ; যেহেতু List<int>এবং List<string>দুটি স্বতন্ত্র নির্মিত ধরণের, একটিতে অন্যটিতে রূপান্তর করা যায় না।

জাভাতে, সংকলক রূপান্তর না করে একটি সাধারণ সুপার টাইপ সন্ধান করার চেষ্টা করে , তাই কোডটি সংকলনে ওয়াইল্ডকার্ড এবং মুছে ফেলা টাইপের অন্তর্নিহিত ব্যবহার জড়িত ;

two > six ? new ArrayList<Integer>() : new ArrayList<String>()

এর কম্পাইল টাইপ হয়েছে ArrayList<?>(আসলে, এটি হতে পারে ArrayList<? extends Serializable>বা ArrayList<? extends Comparable<?>>, ব্যবহার প্রসঙ্গ উপর নির্ভর করে, যেহেতু তারা উভয় সাধারণ জেনেরিক supertypes হয়) এবং কাঁচা এর রানটাইম টাইপ ArrayList(এটা যেহেতু সাধারণ কাঁচা supertype)।

উদাহরণস্বরূপ (এটি নিজে পরীক্ষা করুন) ,

void test( List<?> list ) {
    System.out.println("foo");
}

void test( ArrayList<Integer> list ) { // note: can't use List<Integer> here
                                 // since both test() methods would clash after the erasure
    System.out.println("bar");
}

void test() {
    test( true ? new ArrayList<Object>() : new ArrayList<Object>() ); // foo
    test( true ? new ArrayList<Integer>() : new ArrayList<Object>() ); // foo 
    test( true ? new ArrayList<Integer>() : new ArrayList<Integer>() ); // bar
} // compiler automagically binds the correct generic QED

আসলে Write(two > six ? new List<object>() : new List<string>());কাজ করে না।
blackr1234

4
@ blackr1234 হুবহু: আমি অন্যান্য উত্তরগুলি ইতিমধ্যে যা বলেছি তার পুনরাবৃত্তি করতে চাইনি, তবে ত্রৈমাসিক ভাবটি একটি ধরণের মূল্যায়ন করা দরকার, এবং সংকলক দুটির "সর্বনিম্ন সাধারণ ডিনোমিনেটর" সন্ধান করার চেষ্টা করবে না।
ম্যাথিউ গাইন্ডন

4
প্রকৃতপক্ষে, এটি টাইপ ক্ষয় সম্পর্কে নয়, তবে ওয়াইল্ডকার্ড প্রকারের। এর erasures ArrayList<String>এবং ArrayList<Integer>হবে ArrayList(কাঁচা প্রকার), কিন্তু এই তিন অপারেটর জন্য আমাদের অনুমিত ধরনের ArrayList<?>(ওয়াইল্ডকার্ড টাইপ)। আরও সাধারণভাবে, জাভা রানটাইম টাইপ ইরেজরের মাধ্যমে জেনেরিকগুলি প্রয়োগ করে যে কোনও এক্সপ্রেশনের সংকলন টাইম টাইপের উপর কোনও প্রভাব নেই ।
মেরিটন

4
@ ভ্যাক্সকুইস ধন্যবাদ! আমি সি # লোক, জাভা জেনেরিক আমাকে বিভ্রান্ত করে ;-)
ম্যাথিউ গুইন্ডন

4
আসলে, ধরণ two > six ? new ArrayList<Integer>() : new ArrayList<String>()হল ArrayList<? extends Serializable&Comparable<?>>আপনি টাইপ পরিবর্তনশীল তা নির্ধারণ করতে পারবেন যার মানে ArrayList<? extends Serializable>সেইসাথে ধরনের একটি পরিবর্তনশীল ArrayList<? extends Comparable<?>>, কিন্তু অবশ্যই ArrayList<?>, যা সমতূল্য ArrayList<? extends Object>, যেমন ভাল কাজ করে।
হলগার

6

জাভা এবং সি # (এবং বেশিরভাগ অন্যান্য ভাষা) উভয় ক্ষেত্রেই একটি এক্সপ্রেশনের ফলাফলের একটি প্রকার থাকে। টেরিনারি অপারেটরের ক্ষেত্রে, ফলাফলের জন্য দুটি সম্ভাব্য subexpresstions মূল্যায়ন করা হয় এবং উভয়ের অবশ্যই একই ধরণের থাকতে হবে। জাভা এর ক্ষেত্রে, একটি intভেরিয়েবল Integerঅটোবক্সিং দ্বারা একটিতে রূপান্তর করা যায় । যেহেতু উভয়ই Integerএবং Stringউত্তরাধিকার সূত্রে প্রাপ্ত Object, এগুলি একটি সরু সংকীর্ণ রূপান্তর দ্বারা একই ধরণের রূপান্তরিত হতে পারে।

অন্যদিকে, সি # intতে একটি আদিম এবং সেখানে stringবা অন্য কোনওটিতে অন্তর্নিহিত রূপান্তর নেই object


উত্তর করার জন্য ধন্যবাদ. অটোবক্সিং হ'ল আমি বর্তমানে যা ভাবছি। সি # অটোবক্সিংকে অনুমতি দেয় না?
blackr1234

4
আমি মনে করি না যে এটি সঠিক কারণ কোনও বস্তুর সাথে একটি ইন্টার বক্সিং করা সি # তে পুরোপুরি সম্ভব। এখানে পার্থক্যটি, আমি বিশ্বাস করি যে, সি # এটি অনুমোদিত কিনা তা নির্ধারণের জন্য খুব নড়বড়ে দৃষ্টিভঙ্গি গ্রহণ করে।
জেরোইন ভেনেভেল

9
এটি অটো বক্সিংয়ের সাথে কিছুই করার নেই, যা সি # তে ঠিক তেমন ঘটবে। পার্থক্যটি হ'ল জাভা (কেবল জাভা 5!) করার সময় সি # একটি সাধারণ সুপারটাইপ খুঁজে পাওয়ার চেষ্টা করে না। আপনি সহজেই এটি পরীক্ষা করে দেখতে পারেন যে আপনি যদি 2 টি কাস্টম ক্লাস (যা উভয়ই বস্তু থেকে স্পষ্টতই উত্তরাধিকারসূত্রে প্রাপ্ত হয়) দিয়ে চেষ্টা করেন তবে কী হয় তা দেখার চেষ্টা করে। এছাড়াও থেকে একটি অন্তর্নিহিত রূপান্তর আছে intকরার object
ভু

4
আর nitpick মাত্র একটি বিট আরো থেকে রূপান্তর Integer/Stringকরতে Objectনা কমিয়ে আনায় রূপান্তর, এটা সঠিক বিপরীত হয় :-)
Voo

4
Integerএবং Stringবাস্তবায়ন করে Serializableএবং Comparableতাই তাদের উভয়কেও কার্যভারগুলি কার্যকর হবে, যেমন Comparable<?> c=condition? 6: "6";বা List<? extends Serializable> l = condition? new ArrayList<Integer>(): new ArrayList<String>();আইনী জাভা কোড।
হলগার

5

এই বেশ সহজ. স্ট্রিং এবং ইন্টের মধ্যে কোনও অন্তর্নিহিত রূপান্তর নেই। টেরিনারি অপারেটরের একই ধরণের জন্য শেষ দুটি অপারেটর প্রয়োজন।

চেষ্টা করুন:

Write(two > six ? two.ToString() : "6");

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