'বাহ্য' কীওয়ার্ডটি দুটি আপাতদৃষ্টিতে পৃথক প্রসঙ্গে ব্যবহৃত হয়েছে কেন?


11

সি # তে, outকীওয়ার্ডটি দুটি ভিন্ন উপায়ে ব্যবহার করা যেতে পারে।

  1. প্যারামিটার সংশোধক হিসাবে একটি যুক্তি রেফারেন্স দ্বারা পাস করা হয়

    class OutExample
    {
        static void Method(out int i)
        {
            i = 44;
        }
        static void Main()
        {
            int value;
            Method(out value);
            // value is now 44
        }
    }
  2. Covariance নির্দিষ্ট করতে একটি টাইপ প্যারামিটার সংশোধক হিসাবে

    // Covariant interface. 
    interface ICovariant<out R> { }
    
    // Extending covariant interface. 
    interface IExtCovariant<out R> : ICovariant<R> { }
    
    // Implementing covariant interface. 
    class Sample<R> : ICovariant<R> { }
    
    class Program
    {
        static void Test()
        {
            ICovariant<Object> iobj = new Sample<Object>();
            ICovariant<String> istr = new Sample<String>();
    
            // You can assign istr to iobj because 
            // the ICovariant interface is covariant.
            iobj = istr;
        }
    }

আমার প্রশ্ন: কেন?

কোনও শিক্ষানবিশকে, দুজনের মধ্যে সংযোগটি স্বজ্ঞাত বলে মনে হচ্ছে না । জেনেরিকগুলির সাথে ব্যবহারের উল্লেখটি রেফারেন্স দিয়ে যাওয়ার সাথে কিছু নেই বলে মনে হয়।

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

এই ব্যবহারগুলির মধ্যে কি আমি মিস করছি তার মধ্যে কোনও সংযোগ রয়েছে?


5
যদি আপনি System.Func<in T, out TResult>প্রতিনিধিদের মধ্যে covariance এবং বৈপরীত্য ব্যবহার তাকান তাহলে সংযোগটি কিছুটা বোধগম্য ।
rwong

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

উত্তর:


20

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

লিসকভের প্রতিস্থাপন নীতিটি একবার দেখে নেওয়া যাক :

...

লিসকোভের নীতি স্বাক্ষরগুলির জন্য কিছু স্ট্যান্ডার্ড প্রয়োজনীয়তা আরোপ করে যা নতুন অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং ল্যাঙ্গুয়েজে গৃহীত হয়েছে (সাধারণত ধরণের পরিবর্তে শ্রেণির স্তরে; পার্থক্যের জন্য নামমাত্র বনাম কাঠামোগত সাব-টাইপিং দেখুন):

  • উপ টাইপে পদ্ধতিতে যুক্তিগুলির বৈপরীত্য।
  • উপপ্রকারে রিটার্নের প্রকারের সমাহার।

...

দেখুন কীভাবে বৈষম্য ইনপুট এবং covariance আউটপুট সঙ্গে যুক্ত? সি # তে আপনি যদি কোনও টেম্পলেট ভেরিয়েবলকে outসমবায় রূপান্তরিত করে পতাকাঙ্কিত করেন তবে দয়া করে মনে রাখবেন যে উল্লিখিত প্রকারের পরামিতি কেবল আউটপুট হিসাবে উপস্থিত হবে (ফাংশন রিটার্ন টাইপ)। সুতরাং নিম্নলিখিতটি অবৈধ:

interface I<out T>
{
  void func(T t); //Invalid variance: The type parameter 'T' must be
                  //contravariantly valid on 'I<T>.func(T)'.
                  //'T' is covariant.

}

যদি আপনি কোনও প্রকারের প্যারামিটারটিকে পতাকাঙ্কিত করেন তবে সিমিলারি in, এর অর্থ আপনি এটি কেবল ইনপুট (ফাংশন প্যারামিটার) হিসাবে ব্যবহার করতে পারেন । সুতরাং নিম্নলিখিতটি অবৈধ:

interface I<in T>
{
  T func(); //Invalid variance: The type parameter 'T' must
            //be covariantly valid on 'I<T>.func()'. 
            //'T' is contravariant.

}

সুতরাং সংক্ষিপ্তসার হিসাবে, outকীওয়ার্ডের সাথে সংযোগটি হ'ল ফাংশন প্যারামিটারগুলির সাথে এর অর্থ এটি একটি আউটপুট প্যারামিটার এবং টাইপ পরামিতিগুলির অর্থ এই টাইপটি কেবলমাত্র আউটপুট প্রসঙ্গে ব্যবহৃত হয় ।

System.Funcরওয়ং তার মন্তব্যে যা উল্লেখ করেছে তাও এটি একটি উত্তম উদাহরণ । ইন System.Funcসমস্ত ইনপুট পরামিতি সঙ্গে flaged count = in, এবং আউটপুট পরামিতি সঙ্গে flaged হয় out। কারণটি হ'ল আমি যা বর্ণনা করেছি।


2
চমৎকার উত্তর! আমাকে কিছু বাঁচিয়েছে ... এর জন্য অপেক্ষা করুন ... টাইপিং! যাইহোক, আপনি যে এলএসপিটির উদ্ধৃতি দিয়েছিলেন তা লিসকভের অনেক আগে থেকেই জানা ছিল known এটি কেবল ফাংশনের ধরণের জন্য প্রমিত টাইপিংয়ের নিয়ম। (প্যারামিটারের ধরনগুলি বিপরীতমুখী, রিটার্নের ধরণগুলি কোভেরিয়েন্ট হয়)। Liskov এর পদ্ধতির নতুনত্ব একটি ছিল না) নিয়ম phrasing না সহ- / contravariance পরিপ্রেক্ষিতে কিন্তু behavorial substitutability (যেমন প্রাক / postconditions দ্বারা সংজ্ঞায়িত) এবং খ) পদ ইতিহাস নিয়ম , যা এটি সম্ভব করে তোলে সব এই যুক্তি প্রয়োগ করতে পরিবর্তনীয় ডেটাটাইপগুলিতে, যা আগে সম্ভব ছিল না।
Jörg W Mittag

10

@ গ্যাবার ইতিমধ্যে সংযোগটি ব্যাখ্যা করেছে ("যেভাবে" যায় তার সবের জন্য বৈপরীত্য, যা "আউট" হয় তার সমস্ত ক্ষেত্রে সহজাততা), তবে কেন কীওয়ার্ডগুলি পুনরায় ব্যবহার করবেন?

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

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

inএবং outকীওয়ার্ড ইতিমধ্যে অস্তিত্ব তাই তারা শুধু পুনঃব্যবহৃত করা যেতে পারে।

তারা প্রাসঙ্গিক কীওয়ার্ড যুক্ত করতে পারত যা কোনও প্রকারের প্যারামিটার তালিকার প্রসঙ্গে কেবল কীওয়ার্ড, তবে তারা কী কীওয়ার্ডটি বেছে নেবে? covariantএবং contravariant? +এবং -(উদাহরণস্বরূপ, স্কালার মতো করেছিলেন)? superএবং extendsজাভা মত করে? আপনি কি আপনার মাথার উপরের অংশটি মনে করতে পারেন কোন প্যারামিটারগুলি সমবায় এবং বিপরীত?

বর্তমান সমাধানের সাথে একটি দুর্দান্ত স্মৃতিভিত্তিক outশব্দ রয়েছে : আউটপুট ধরণের পরামিতিগুলি মূল শব্দটি পায়, ইনপুট ধরণের পরামিতিগুলি inকীওয়ার্ডটি পায়। পদ্ধতির পরামিতিগুলির সাথে দুর্দান্ত প্রতিসাম্যটি নোট করুন: আউটপুট প্যারামিটারগুলি outকীওয়ার্ডটি পায়, ইনপুট পরামিতিগুলি inকীওয়ার্ডটি পায় (ভাল, আসলে, কোনও কীওয়ার্ড নেই, যেহেতু ইনপুটটি ডিফল্ট, তবে আপনি ধারণাটি পান)।

[দ্রষ্টব্য: আপনি সম্পাদনা ইতিহাসের দিকে নজর দিলে আপনি দেখতে পাবেন যে আমি আসলে আমার সূচনা বাক্যে দুটি মূল পরিবর্তন করেছি। এমনকি আমি সেই সময়ে একটি উপভোগও পেয়েছি! এটি কেবল আপনাকে স্মরণ করিয়ে দেয় যে স্মৃতিবিদ্যার সত্যতা কতটা গুরুত্বপূর্ণ]]


সহ-বনাম বৈসাদৃশ্যগুলি মনে রাখার উপায়টি বিবেচনা করা হয় যদি কোনও ইন্টারফেসের কোনও ফাংশন জেনেরিক ইন্টারফেস ধরণের পরামিতি নেয় তবে কী ঘটে। এক একটি থাকে interface Accepter<in T> { void Accept(T it);};, একটি Accepter<Foo<T>>গ্রহণ করবে Tএকটি ইনপুট প্যারামিটার হিসাবে যদি Foo<T>এটি একটি আউটপুট প্যারামিটার হয়, এবং তদ্বিপরীত হিসাবে গ্রহণ করে। সুতরাং, বিরূদ্ধে -variance। বিপরীতে, interface ISupplier<out T> { T get();};একটি Supplier<Foo<T>>বিচ্ছিন্নতা আছে যা কিছু Fooআছে - এইভাবে সহাবস্থান
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.