একটি ইন্টারফেস বনাম সাধারণভাবে সীমাবদ্ধ প্রকারের কারণ কী What


15

জেনেরিক ধরণের প্যারামিটারগুলিকে সমর্থন করে এমন বস্তু-ভিত্তিক ভাষায় (ক্লাস টেম্পলেট এবং প্যারাম্যাট্রিক বহুবর্ষ হিসাবে পরিচিত, যদিও প্রতিটি নাম বিভিন্ন রূপ ধারণ করে) তবে প্রায়শই টাইপ প্যারামিটারে কোনও ধরণের সীমাবদ্ধতা নির্দিষ্ট করা সম্ভব হয়, যেমন এটি অবতরণ হয় that অন্য ধরনের থেকে। উদাহরণস্বরূপ, এটি সি # তে সিনট্যাক্স:

//for classes:
class ExampleClass<T> where T : I1 {

}
//for methods:
S ExampleMethod<S>(S value) where S : I2 {
        ...
}

সেই ইন্টারফেসগুলির দ্বারা সীমাবদ্ধ ধরণের প্রকৃত ইন্টারফেস প্রকারগুলি ব্যবহার করার কারণগুলি কী কী? উদাহরণস্বরূপ, পদ্ধতিটি স্বাক্ষর করার কারণগুলি কী কী I2 ExampleMethod(I2 value)?


4
শ্রেণীর টেম্পলেটগুলি (সি ++) হ'ল পরিমাপের জেনেরিকের চেয়ে সম্পূর্ণ আলাদা এবং আরও শক্তিশালী are যদিও জেনেরিক ভাষা রয়েছে তাদের জন্য টেমপ্লেট সিনট্যাক্স ধার নিয়েছে।
উত্সাহক

ইন্টারফেস পদ্ধতি হ'ল পরোক্ষ কল, যেখানে টাইপ পদ্ধতিগুলি সরাসরি কল হতে পারে। সুতরাং আধুনিকটি পূর্বের চেয়ে দ্রুততর হতে পারে এবং refমান ধরণের পরামিতিগুলির ক্ষেত্রে, মান ধরণেরটিকে সংশোধন করতে পারে।
ব্যবহারকারী541686

@ প্রতিলিপি: জেনেরিকগুলি টেমপ্লেটগুলির চেয়ে পুরোনো বলে বিবেচনা করে আমি জেনারিকরা টেমপ্লেটগুলি থেকে সিনট্যাক্স বা অন্য কোনও উপায়ে কীভাবে কিছু ধার নিতে পারত তা দেখতে আমি ব্যর্থ।
Jörg ডব্লু মিটাগ

3
@ জার্গডব্লিউমিত্যাগ: আমি সন্দেহ করি যে "জেনারিকসকে সমর্থন করে এমন অবজেক্ট-ভিত্তিক ভাষা" দ্বারা ডিডুকিপেটর "এমএল এবং অ্যাডা" না দিয়ে "জাভা এবং সি #" বুঝতে পেরেছিলেন। তারপরে জেনারিকস বা প্যারাম্যাট্রিক পলিমারফিজমযুক্ত সমস্ত ভাষা সি ++ থেকে ধার নেওয়া সত্ত্বেও পূর্বেরটির উপর সি ++ এর প্রভাব স্পষ্ট ।
স্টিভ জেসোপ

2
@ স্টিভ জেসোপ: এমএল, অ্যাডা, আইফেল, হাস্কেল সি ++ টেম্পলেট, স্কালা, এফ #, ওক্যামেল পরে এসেছিল এবং তাদের কেউই সি ++ এর বাক্য গঠন ভাগ করে নি। (মজার বিষয় হল, এমনকি ডি, যা সি ++, বিশেষত টেম্পলেটগুলি থেকে প্রচুর bণ নিয়েছে, সি ++ এর বাক্যবিন্যাসটি ভাগ করে না)) "জাভা এবং সি #" "জেনেরিক ভাষাগুলি থাকার" ভাষাগুলির একটি বরং সংকীর্ণ দৃষ্টিভঙ্গি বলে মনে করি।
Jörg ডব্লু মিটাগ

উত্তর:


21

প্যারামেট্রিক সংস্করণ ব্যবহার করে দেয়

  1. ফাংশন ব্যবহারকারীদের আরও তথ্য
  2. আপনি যে পরিমাণ প্রোগ্রাম লিখতে পারেন তা সীমাবদ্ধ করে (বিনামূল্যে বাগ চেকিং)

একটি এলোমেলো উদাহরণ হিসাবে, ধরুন আমাদের কাছে এমন একটি পদ্ধতি রয়েছে যা চতুর্ভুজ সমীকরণের শিকড় গণনা করে

int solve(int a, int b, int c) {
  // My 7th grade math teacher is laughing somewhere
}

এবং তারপর আপনি এটা ছাড়া ভীষণ পছন্দ সংখ্যা অন্যান্য প্রকারের উপর কাজ করতে চান int। আপনি যেমন কিছু লিখতে পারেন

Num solve(Num a, Num b, Num c){
  ...
}

সমস্যাটি হ'ল এটি আপনি যা চান তা বলে না। এটা বলে

আমাকে সংখ্যার মতো যে কোনও 3 টি জিনিস দিন (অগত্যা একইভাবে নয়) এবং আমি আপনাকে কিছু সংখ্যক ফিরিয়ে দেব

আমরা ভালো কিছু করতে পারেন না int sol = solve(a, b, c)যদি a, bএবং cহয় intকারণ আমরা জানি না পদ্ধতি একটি ফিরে যাচ্ছে গুলি intশেষ! এটি যদি আমরা কোনও বৃহত্তর অভিব্যক্তিতে সমাধানটি ব্যবহার করতে চাই তবে ডাউনকাস্টিংয়ের সাথে কিছু বিশ্রী নাচ এবং প্রার্থনা করার দিকে পরিচালিত করে।

ফাংশনের অভ্যন্তরে, কেউ আমাদের কাছে একটি ভাসা, বিগিন্ট এবং ডিগ্রি সরবরাহ করতে পারে এবং আমরা সেগুলি যোগ করতে এবং একসাথে বহুগুণ করতে চাই। আমরা এটিকে স্থিতিশীলভাবে প্রত্যাখ্যান করতে চাই কারণ এই 3 টি শ্রেণির মধ্যে ক্রিয়াকলাপগুলি গীবর হতে চলেছে। ডিগ্রিগুলি মোড 360 হয় তাই এটির ক্ষেত্রে এমনটি হবে না a.plus(b) = b.plus(a)এবং একই রকম ilaষধিটি দেখা দেবে।

আমরা যদি সাব-টাইপিংয়ের মাধ্যমে প্যারামেট্রিক পলিমারফিজম ব্যবহার করি তবে আমরা এই সমস্ত বিষয়টিকে নিয়ম করে দেখতে পারি কারণ আমাদের ধরণটি আসলে আমাদের অর্থ কী বলে

<T : Num> T solve(T a, T b, T c)

বা কথায় কথায় "আপনি যদি আমাকে এমন কোনও প্রকার দেন যা একটি সংখ্যা হয় তবে আমি সেই সহগগুলির সাথে সমীকরণগুলি সমাধান করতে পারি"।

এটি অন্যান্য অনেক জায়গাতেও আসে। উদাহরণ আরেকটি ভাল উৎস ফাংশন যা বিমূর্ত ধারক, Ala কিছু বাছাই ধরে আছে reverse, sort, map, ইত্যাদি


8
সংক্ষেপে, জেনেরিক সংস্করণ গ্যারান্টি দেয় যে তিনটি ইনপুট (এবং আউটপুট) একই ধরণের সংখ্যার হবে।
গাণিতিক

যাইহোক, আপনি প্রশ্নের ধরণটি নিয়ন্ত্রণ না করে (এবং এটি এতে কোনও ইন্টারফেস যোগ করতে পারে না) এগুলি সংক্ষিপ্ত হয়। সর্বোচ্চ সাধারণতার জন্য আপনাকে আর্গুমেন্টের ধরণের (যেমন Num<int>) অতিরিক্ত আর্গুমেন্ট হিসাবে প্যারামিট্রাইজ করা একটি ইন্টারফেস গ্রহণ করতে হবে । আপনি প্রতিনিধিদের মাধ্যমে যে কোনও ধরণের ইন্টারফেসটি সর্বদা বাস্তবায়ন করতে পারেন। এটি হেস্কেলের ধরণের ক্লাসগুলি মূলত যা হ'ল ব্যবহার করার জন্য আরও ক্লান্তিকর বাদে যেহেতু আপনাকে স্পষ্টভাবে ইন্টারফেসের চারপাশে পাস করতে হবে।
ডোভাল

16

সেই ইন্টারফেসগুলির দ্বারা বাধিত ধরণের উপর প্রকৃত ইন্টারফেস প্রকারগুলি ব্যবহার করার কারণগুলি কি?

কারণ এটাই আপনার দরকার ...

IFoo Fn(IFoo x);
T Fn<T>(T x) where T: IFoo;

দুটি স্থির পৃথক স্বাক্ষর। প্রথম যে কোনও লাগে ধরণের ইন্টারফেস প্রয়োগ করে এবং একমাত্র গ্যারান্টি দেয় এটি হ'ল প্রত্যাবর্তন মান ইন্টারফেসটি সন্তুষ্ট করে।

দ্বিতীয়টি ইন্টারফেস প্রয়োগকারী যেকোন ধরণের গ্রহণ করে এবং গ্যারান্টি দেয় যে এটি কমপক্ষে সেই ধরণের আবার ফিরে আসবে (বরং এমন কিছু যা কম সীমাবদ্ধ ইন্টারফেসটি সন্তুষ্ট করে)।

কখনও কখনও, আপনি দুর্বল গ্যারান্টি চান। কখনও কখনও আপনি আরও শক্তিশালী চান।


আপনি কীভাবে দুর্বল গ্যারান্টি সংস্করণটি ব্যবহার করবেন তার একটি উদাহরণ দিতে পারেন?
গ্রেগরোস

4
@ গ্রেগরোস - উদাহরণস্বরূপ, আমি কিছু পার্সার কোড লিখেছি। আমি একটি ফাংশন পেয়েছি Orযা দুটি Parserঅবজেক্ট (একটি বিমূর্ত বেস শ্রেণি, তবে নীতিটি ধারণ করে) নিয়ে যায় এবং একটি নতুন Parser(তবে ভিন্ন ধরণের সহ) ফেরত দেয় । শেষ ব্যবহারকারীর কংক্রিটের প্রকারটি কী তা জানা বা যত্ন নেওয়া উচিত নয়।
টেলাস্টিন

সি # তে আমি কল্পনা করেছি যে পাস করা একটি ব্যতীত অন্য কোনও টির ফিরিয়ে দেওয়া নতুন সীমাবদ্ধতা ব্যতীত প্রায় অসম্ভব (ডাব্লু / ও রিফ্লেকশন ব্যথা) পাশাপাশি আপনার দৃ guarantee় গ্যারান্টিটি নিজের পক্ষে একেবারেই অকেজো করে তোলে।
এনটিএসকোবাল্ট

1
@ এনটিএসকোবাল্ট: আপনি যখন প্যারামেট্রিক এবং ইন্টারফেস জেনেরিক প্রোগ্রামিং উভয়কে একত্রিত করেন তখন এটি আরও কার্যকর। উদাহরণস্বরূপ লিনকুই সবসময় কী করে (কোনও গ্রহণ করে IEnumerable<T>, অন্যটি দেয় IEnumerable<T>যা প্রকৃত অর্থে একটি OrderedEnumerable<T>)
বেন ভয়েগট

2

পদ্ধতির পরামিতিগুলির জন্য সীমাবদ্ধ জেনেরিকগুলির ব্যবহার কোনও পদ্ধতিটিকে তার পাসওয়ার্ডের উপর ভিত্তি করে তার রিটার্ন টাইপটিকে খুব মঞ্জুরি দেয় N NET এ তাদের অতিরিক্ত সুবিধাও পেতে পারে। তাদের মধ্যে:

  1. একটি পদ্ধতি যা একটি সীমাবদ্ধ জেনেরিকে একটি refবা outপরামিতি হিসাবে গ্রহণ করে এমন একটি ভেরিয়েবল পাস হতে পারে যা সীমাবদ্ধ করে; বিপরীতে, একটি ইন্টারফেস-টাইপ প্যারামিটার সহ একটি অ-জেনেরিক পদ্ধতি সেই সঠিক ইন্টারফেস টাইপের ভেরিয়েবলগুলি গ্রহণের মধ্যে সীমাবদ্ধ থাকবে।

  2. জেনেরিক টাইপ প্যারামিটার টি সহ একটি পদ্ধতি টি এর জেনেরিক সংগ্রহগুলি গ্রহণ IList<T> where T:IAnimalকরতে পারে List<SiameseCat>an IList<Animal>এমন একটি পদ্ধতি যা একটি গ্রহণ করে তা একটি গ্রহণ করতে সক্ষম হবে , তবে যে পদ্ধতিটি এটি চেয়েছিল তা করতে সক্ষম হবে না।

  3. একটি বাধা কখনও কখনও জেনেরিক ধরণের ক্ষেত্রে যেমন একটি ইন্টারফেস নির্দিষ্ট করতে পারে where T:IComparable<T>

  4. একটি কাঠামো যা ইন্টারফেস প্রয়োগ করে একটি মান টাইপ হিসাবে রাখা যেতে পারে যখন একটি জড়িত জেনেরিক পরামিতি গ্রহণের পদ্ধতিতে পাঠানো হয় তবে ইন্টারফেসের ধরণ হিসাবে পাস করার পরে অবশ্যই বাক্সবিন্যাস করতে হবে। এটি গতিতে বিশাল প্রভাব ফেলতে পারে।

  5. জেনেরিক প্যারামিটারে একাধিক বাধা থাকতে পারে, যখন "IFoo এবং IBar উভয়ই প্রয়োগ করে এমন কোনও ধরণের পরামিতি নির্দিষ্ট করার কোনও উপায় নেই। কখনও কখনও এটি একটি দ্বি প্রান্তযুক্ত তরোয়াল হতে পারে, যেহেতু কোড যা টাইপের একটি প্যারামিটার পেয়েছে IFooতাতে দ্বি-সীমাবদ্ধ জেনেরিকের প্রত্যাশা এমন পদ্ধতিতে এটি পাস করা খুব কঠিন হবে, এমনকি যদি প্রশ্নযুক্ত উদাহরণটি সমস্ত প্রতিবন্ধকতাগুলি পূরণ করে।

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

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