সি # ইন্টারফেস। সুস্পষ্ট বাস্তবায়ন বনাম স্পষ্ট বাস্তবায়ন


632

ইন্টারফেসগুলি বাস্তবায়নে পার্থক্য কি কি পরোক্ষভাবে এবং স্পষ্টভাবে C #?

কখন আপনাকে অন্তর্ভুক্ত ব্যবহার করা উচিত এবং কখন আপনাকে স্পষ্টভাবে ব্যবহার করা উচিত?

একটি বা অন্যের পক্ষে কোনও উপকার এবং / অথবা কনস আছে?


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

আমি মনে করি এই নির্দেশিকাটি প্রাক-আইওসি-সময়ে খুব বৈধ , যখন আপনি চারপাশের জিনিসগুলিকে ইন্টারফেস হিসাবে পাস করেন না।

কেউ কি সেই দিকটি স্পর্শ করতে পারে?


সি # ইন্টারফেসে সম্পূর্ণ নিবন্ধটি পড়ুন: গ্রাণোফকোডার্স
গৌরব

হ্যাঁ, সুস্পষ্ট ইন্টারফেসগুলি এড়ানো উচিত এবং আইএসপি প্রয়োগ করার জন্য আরও পেশাদার পদ্ধতির (ইন্টারফেস বিভাজন নীতি) এখানে একই কোডড্রজেক্ট
শিবপ্রসাদ কৈরালা

উত্তর:


492

অন্তর্নিহিত হয় যখন আপনি আপনার ক্লাসের কোনও সদস্যের মাধ্যমে আপনার ইন্টারফেসটি সংজ্ঞায়িত করেন। স্পষ্ট হয় যখন আপনি ইন্টারফেসে আপনার শ্রেণীর মধ্যে পদ্ধতিগুলি নির্ধারণ করেন। আমি জানি যে বিভ্রান্তিকর শোনায় তবে এখানে আমি যা বলতে চাইছি তা হল: IList.CopyToস্পষ্টভাবে এই হিসাবে প্রয়োগ করা হবে:

public void CopyTo(Array array, int index)
{
    throw new NotImplementedException();
}

এবং স্পষ্টভাবে হিসাবে:

void ICollection.CopyTo(Array array, int index)
{
    throw new NotImplementedException();
}

পার্থক্যটি হ'ল অন্তর্নিহিত বাস্তবায়ন আপনাকে সেই শ্রেণি হিসাবে এবং ইন্টারফেস হিসাবে নিজের ইন্টারফেসটি ingালার মাধ্যমে আপনি তৈরি ক্লাসের মাধ্যমে ইন্টারফেস অ্যাক্সেস করতে পারবেন। সুস্পষ্ট বাস্তবায়ন আপনাকে কেবল ইন্টারফেস হিসাবে নিজেকে কাস্ট করে ইন্টারফেস অ্যাক্সেস করতে দেয়।

MyClass myClass = new MyClass(); // Declared as concrete class
myclass.CopyTo //invalid with explicit
((IList)myClass).CopyTo //valid with explicit.

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

আমি নিশ্চিত যে অন্যরা পোস্ট করবে এমন স্পষ্টভাবে ব্যবহার / ব্যবহার না করার আরও অনেক কারণ রয়েছে।

প্রত্যেকের পিছনে দুর্দান্ত যুক্তির জন্য এই থ্রেডের পরবর্তী পোস্টটি দেখুন ।


8
আমি জানি এই পোস্টটি পুরানো তবে আমি এটি খুব দরকারী বলে মনে করেছি - একটি বিষয় লক্ষ্যণীয় যে এটি পরিষ্কার নয় কারণ এটি আমার কাছে ছিল না তা উদাহরণটিতে অন্তর্নিহিত ব্যক্তির মূলশব্দটি ছিল public... অন্যথায় আপনি একটি ত্রুটি পাবেন
jharr100

সি # 4 এড সিএইচ 13 এর মাধ্যমে জেফ্রি রিখটারের সিএলআর একটি উদাহরণ দেখায় যেখানে কাস্টিংয়ের প্রয়োজন নেই: অভ্যন্তরীণ কাঠামো সামভালিউটাইপ: আইকোম্পারেবল {বেসরকারী ইন্টার 32 এম_এক্স; সর্বজনীন সামোভ্যালিউটাইপ (অন্তর্গত x x) {এম_এক্স = এক্স; } সার্বজনীন Int32 CompareTo (SomeValueType other) {...); 32 Int32 IComparable.CompareTo (অন্য অবজেক্ট) {রিটার্ন তুলনা করুন ((সামারভ্যালিউটাইপ) অন্যান্য); }} পাবলিক স্ট্যাটিক অকার্যকর মেইন () {সোমারভ্যালিউটাইপ v = নতুন কিছু ভ্যালু টাইপ (0); অবজেক্ট o = নতুন অবজেক্ট (); Int32 n = v.CompareTo (v); // কোন বক্সিং n = v.CompareTo (ও); // সংকলন-সময় ত্রুটি}
অ্যান্ডি ডেন্ট

1
আজ আমি একটি বিরল পরিস্থিতির মুখোমুখি হয়েছি যা একটি স্পেসিফিক ইন্টারফেসের ব্যবহারের প্রয়োজন: একটি ইন্টারফেস নির্মাতার দ্বারা উত্পন্ন ক্ষেত্রের সাথে একটি শ্রেণি যা ক্ষেত্রটি ব্যক্তিগত হিসাবে তৈরি করে (আইওএস স্টোরিবোর্ড ব্যবহার করে জ্যামারিন আইওএসকে লক্ষ্য করে)। এবং একটি ইন্টারফেস যেখানে এটি ক্ষেত্রটি প্রকাশ করার জন্য (জনসাধারণের পঠনযোগ্য) বোধগম্য হয়েছিল। আমি ইন্টারফেসে প্রাপ্তকারীর নাম পরিবর্তন করতে পারতাম, তবে বিদ্যমান নামটি ছিল অবজেক্টটির সর্বাধিক যৌক্তিক নাম। সুতরাং পরিবর্তে আমি একটি সুনির্দিষ্ট বাস্তবায়ন ব্যক্তিগত ক্ষেত্র উল্লেখ করেছে: UISwitch IScoreRegPlayerViewCell.markerSwitch { get { return markerSwitch; } }
টুলমেকারস্টেভ

1
প্রোগ্রামিং এর ভয়াবহতা। ভাল, সুন্দরভাবে ডিবাঙ্কড!
তরল কোর

1
@ টুলমেকারস্টিভ আরেকটি পরিস্থিতি (বরং আরও সাধারণ) যার জন্য কমপক্ষে একজন ইন্টারফেস সদস্যের সুস্পষ্ট বাস্তবায়ন প্রয়োজন এমন একাধিক ইন্টারফেস বাস্তবায়িত করা হচ্ছে যা একই স্বাক্ষরযুক্ত তবে ভিন্ন রিটার্নের ধরণের সদস্য রয়েছে। যেমন কিছু করে এই ইন্টারফেস উত্তরাধিকার কারণে ঘটতে পারে IEnumerator<T>.Current, IEnumerable<T>.GetEnumerator()এবং ISet<T>.Add(T)। এটি অন্য উত্তরে উল্লেখ করা হয়েছে ।
ফুগ

201

অন্তর্নিহিত সংজ্ঞাটি হ'ল কেবল ক্লাসে ইন্টারফেসের দ্বারা দাবি করা পদ্ধতি / বৈশিষ্ট্যাদি ইত্যাদি পাবলিক পদ্ধতি হিসাবে যুক্ত করা।

সুস্পষ্ট সংজ্ঞা সদস্যদের তখনই উন্মুক্ত করতে বাধ্য করে যখন আপনি সরাসরি ইন্টারফেসের সাথে কাজ করছেন, এবং অন্তর্নিহিত বাস্তবায়ন নয়। এটি বেশিরভাগ ক্ষেত্রেই পছন্দ করা হয়।

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

2
আপনি এখানে কিছু ভাল পয়েন্ট তৈরি করুন। বিশেষত এ। আমি সাধারণত আমার ক্লাসগুলি ইন্টারফেস হিসাবে যাইহোক যাইহোক পাস করি, তবে আমি কখনই এটিকে সেই দৃষ্টিকোণটি রূপ দেওয়ার বিষয়ে ভাবিনি।
ম্যাটল্যান্ট

5
আমি নিশ্চিত নই যে আমি বিন্দু সি এর সাথে একমত, একটি বিড়াল বস্তু আইয়্যাটেবল প্রয়োগ করতে পারে তবে খাওয়া () জিনিসটির একটি মৌলিক অংশ। আপনি যখন আইয়্যাটেবল ইন্টারফেসের পরিবর্তে 'কাঁচা' অবজেক্টটি ব্যবহার করছেন তখন আপনি একটি বিড়ালের উপর কেবল ইট () কল করতে চান এমন কিছু ক্ষেত্রে আছে, না?
কিংবদন্তি দৈর্ঘ্য

59
আমি এমন কিছু জায়গাগুলি জানি যেখানে Catসত্যই IEatableআপত্তি নেই ections
হামবার্তো

26
আমি উপরোক্ত সকলের সাথে সম্পূর্ণই একমত নই এবং আমি বলব যে স্পষ্ট ইন্টারফেস ব্যবহার করা বিপর্যয়ের রেসিপি এবং
ওওপি বা ওওডি


68

ইতিমধ্যে সরবরাহ করা দুর্দান্ত উত্তরের পাশাপাশি, এমন কয়েকটি মামলা রয়েছে যেখানে সংকলকটির জন্য কী প্রয়োজন তা নির্ধারণের জন্য সুস্পষ্ট বাস্তবায়ন প্রয়োজন। একবার দেখুনIEnumerable<T>প্রধান উদাহরণ হিসাবে যা সম্ভবত প্রায়শই প্রায়শই উপস্থিত হবে।

এখানে একটি উদাহরণ:

public abstract class StringList : IEnumerable<string>
{
    private string[] _list = new string[] {"foo", "bar", "baz"};

    // ...

    #region IEnumerable<string> Members
    public IEnumerator<string> GetEnumerator()
    {
        foreach (string s in _list)
        { yield return s; }
    }
    #endregion

    #region IEnumerable Members
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
    #endregion
}

এখানে, IEnumerable<string>প্রয়োগ IEnumerable, তাই আমাদের খুব প্রয়োজন। তবে স্থির থাকুন, জেনেরিক এবং সাধারণ সংস্করণ উভয়ই একই পদ্ধতির স্বাক্ষরের সাথে ফাংশন প্রয়োগ করে (সি # এর জন্য রিটার্নের ধরণের উপেক্ষা করে)। এটি সম্পূর্ণ আইনী এবং জরিমানা। সংকলক কীভাবে ব্যবহার করবে তা সমাধান করবে? এটি আপনাকে কেবলমাত্র অন্তত একটি অন্তর্নিহিত সংজ্ঞা রাখতে বাধ্য করে, তারপরে এটি যা প্রয়োজন তা সমাধান করতে পারে।

অর্থাত।

StringList sl = new StringList();

// uses the implicit definition.
IEnumerator<string> enumerableString = sl.GetEnumerator();
// same as above, only a little more explicit.
IEnumerator<string> enumerableString2 = ((IEnumerable<string>)sl).GetEnumerator();
// returns the same as above, but via the explicit definition
IEnumerator enumerableStuff = ((IEnumerable)sl).GetEnumerator();

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


5
@ তাসাদাক: 2 বছর পরে, আমি কেবল বলতে পারি "গুড প্রশ্ন"। আমার কোন ধারণা, সম্ভবত ছাড়া আমি যে কোড কিছু থেকে আমি এটি ছিল যেখানে কাজ ছিল কপি আছে abstract
ম্যাথু শার্লে

4
@ তাসাদ্দেক, আপনি সঠিক বলেছেন, তবে আমার মতে উপরে ম্যাথু শার্লির পোস্টের বিন্দুটি হারিয়ে যায়নি।
ফানকিমশরুম

35

সিএলআর থেকে সি # এর মাধ্যমে জেফ্রি রিখরটাকে উদ্ধৃত করতে
( ইআইএমআই অর্থ এক্সপ্লিকেশন আমি ইটারপ্লেক্স এম ইথুথাল আই ম্যাপলমেন্টেশন)

EIMIs ব্যবহার করার সময় বিদ্যমান কিছু র‌্যামিকেশনগুলি বোঝার জন্য আপনার পক্ষে সমালোচনামূলকভাবে গুরুত্বপূর্ণ। এবং এই পদক্ষেপগুলির কারণে আপনার যতটা সম্ভব ইআইএমআই এড়ানোর চেষ্টা করা উচিত। ভাগ্যক্রমে, জেনেরিক ইন্টারফেস আপনাকে EIMI গুলি কিছুটা এড়াতে সহায়তা করে। তবে এখনও অনেক সময় থাকতে পারে যখন আপনার সেগুলি ব্যবহার করতে হবে (যেমন একই নাম এবং স্বাক্ষরের সাথে দুটি ইন্টারফেস পদ্ধতি প্রয়োগ করা)। এখানে ইআইএমআই সহ বড় সমস্যা রয়েছে:

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

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

আইআইএনআইএমএল <টি> এর মতো বেসিক ফ্রেমওয়ার্ক ইন্টারফেসের বাস্তবায়নগুলি থেকে অ-দৃ strongly়ভাবে টাইপযুক্ত ইন্টারফেস সদস্যদের আড়াল করতে EIMI গুলিও ব্যবহার করা যায় যাতে আপনার ক্লাসটি কোনও দৃ strongly়ভাবে টাইপ করা পদ্ধতি সরাসরি প্রকাশ না করে, তবে বাক্য গঠনগত সঠিক।


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

4
@ ভ্যালেন্টিন ইএমআই এবং আইইএমআই এর পক্ষে কী?
ডিজিয়ান

সুস্পষ্ট ইন্টারফেস পদ্ধতি বাস্তবায়ন
স্কোবি

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

1
"একটি EIMI ডেরিভেট টাইপ দ্বারা কল করা যায় না" " << কি? এটা সত্যি না. যদি আমি স্পষ্টভাবে কোনও ধরণের একটি ইন্টারফেস প্রয়োগ করি, তবে আমি সেই ধরণের থেকে উদ্ভূত হয়েছি, আমি এখনও পদ্ধতিটি কল করার জন্য ইন্টারফেসে এটি কাস্ট করতে পারি, ঠিক যেমনটি প্রয়োগ করা হয়েছে তার জন্য আমার যেমন করতে হবে। সুতরাং আপনি কী বিষয়ে কথা বলছেন তা নিশ্চিত হন না। এমনকি উদ্ভূত প্রকারের মধ্যেও, স্পষ্টভাবে প্রয়োগকৃত পদ্ধতিতে পৌঁছাতে আমি কেবল প্রশ্নটির ইন্টারফেসে "এটি" দিতে পারি cast
ট্রায়ঙ্কো

34

কারণ # 1

আমি যখন "প্রোগ্রামিংকে একটি বাস্তবায়নে নিরুত্সাহিত করতে চাই" ( ডিজাইনের প্যাটার্নস থেকে ডিজাইনের নীতিগুলি ) চাই তখন আমি স্পষ্টত ইন্টারফেস বাস্তবায়ন ব্যবহার করি ।

উদাহরণস্বরূপ, একটি এমভিপি ভিত্তিক ওয়েব অ্যাপ্লিকেশনটিতে:

public interface INavigator {
    void Redirect(string url);
}

public sealed class StandardNavigator : INavigator {
    void INavigator.Redirect(string url) {
        Response.Redirect(url);
    }
}

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

কারণ # 2

একটি স্পষ্ট ইন্টারফেস বাস্তবায়নের সাথে আমি যেতে পারি এমন আরও একটি কারণ হ'ল কোনও শ্রেণীর "ডিফল্ট" ইন্টারফেস ক্লিনার রাখা। উদাহরণস্বরূপ, আমি যদি একটি এএসপি.এনইটি সার্ভার নিয়ন্ত্রণ বিকাশ করতাম তবে আমি দুটি ইন্টারফেস চাইব:

  1. শ্রেণীর প্রাথমিক ইন্টারফেস, যা ওয়েব পৃষ্ঠা বিকাশকারীরা ব্যবহার করেন; এবং
  2. নিয়ন্ত্রণের যুক্তি সামলানোর জন্য উপস্থাপকের দ্বারা ব্যবহৃত একটি "লুকানো" ইন্টারফেস

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

public sealed class CustomerComboBox : ComboBox, ICustomerComboBox {
    private readonly CustomerComboBoxPresenter presenter;

    public CustomerComboBox() {
        presenter = new CustomerComboBoxPresenter(this);
    }

    protected override void OnLoad() {
        if (!Page.IsPostBack) presenter.HandleFirstLoad();
    }

    // Primary interface used by web page developers
    public Guid ClientId {
        get { return new Guid(SelectedItem.Value); }
        set { SelectedItem.Value = value.ToString(); }
    }

    // "Hidden" interface used by presenter
    IEnumerable<CustomerDto> ICustomerComboBox.DataSource { set; }
}

উপস্থাপক ডেটা উত্সকে জনপ্রিয় করে তোলে এবং ওয়েব পৃষ্ঠা বিকাশকারীকে কখনই এর অস্তিত্ব সম্পর্কে সচেতন হওয়া দরকার না।

তবে এটি ইজ নট সিলভার ক্যাননবল

আমি সবসময় সুস্পষ্ট ইন্টারফেস বাস্তবায়ন নিয়োগের পরামর্শ দেব না। এগুলি মাত্র দুটি উদাহরণ যেখানে তারা সহায়ক হতে পারে।


19

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

/// <summary>
/// This is a Book
/// </summary>
interface IBook
{
    string Title { get; }
    string ISBN { get; }
}

/// <summary>
/// This is a Person
/// </summary>
interface IPerson
{
    string Title { get; }
    string Forename { get; }
    string Surname { get; }
}

/// <summary>
/// This is some freaky book-person.
/// </summary>
class Class1 : IBook, IPerson
{
    /// <summary>
    /// This method is shared by both Book and Person
    /// </summary>
    public string Title
    {
        get
        {
            string personTitle = "Mr";
            string bookTitle = "The Hitchhikers Guide to the Galaxy";

            // What do we do here?
            return null;
        }
    }

    #region IPerson Members

    public string Forename
    {
        get { return "Lee"; }
    }

    public string Surname
    {
        get { return "Oades"; }
    }

    #endregion

    #region IBook Members

    public string ISBN
    {
        get { return "1-904048-46-3"; }
    }

    #endregion
}

এই কোডটি সংকলন করে ওকে চলে, তবে শিরোনামের সম্পত্তিটি ভাগ করা আছে।

স্পষ্টতই, আমরা চাই যে শিরোনামের মানটি আমরা ক্লাস 1 বা কোনও ব্যক্তি হিসাবে বিবেচনা করছিলাম কিনা তার উপর নির্ভর করে to এটি তখনই হয় যখন আমরা স্পষ্টত ইন্টারফেসটি ব্যবহার করতে পারি।

string IBook.Title
{
    get
    {
        return "The Hitchhikers Guide to the Galaxy";
    }
}

string IPerson.Title
{
    get
    {
        return "Mr";
    }
}

public string Title
{
    get { return "Still shared"; }
}

লক্ষ করুন যে সুস্পষ্ট ইন্টারফেস সংজ্ঞাগুলি সর্বজনীন হতে অনুমিত করা হয়েছে - এবং সুতরাং আপনি এগুলি স্পষ্টভাবে প্রকাশ্যে (বা অন্যথায়) ঘোষণা করতে পারবেন না।

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

যদি আপনি "ভাগ করা" (অন্তর্নিহিত) শিরোনামটি সংজ্ঞায়িত না করেন তবে ক্লাস 1 এর গ্রাহকরা অবশ্যই প্রথমে ক্লাস 1 এর উদাহরণগুলি প্রথমে আইবুক বা আইফারসনকে দিতে হবে - অন্যথায় কোডটি সংকলন করবে না।


16

আমি বেশিরভাগ সময় স্পষ্টত ইন্টারফেস প্রয়োগ করি। এখানে মূল কারণ রয়েছে।

রিফ্যাক্টরিং নিরাপদ

কোনও ইন্টারফেস পরিবর্তন করার সময়, সংকলক এটি পরীক্ষা করতে পারলে ভাল। অন্তর্নিহিত বাস্তবায়ন সহ এটি আরও শক্ত।

দুটি সাধারণ ক্ষেত্রে মাথায় আসে:

  • একটি ইন্টারফেসে একটি ফাংশন যুক্ত করা, যেখানে একটি বিদ্যমান শ্রেণি যা এই ইন্টারফেসটি প্রয়োগ করে ইতিমধ্যে নতুনটির মতো একই স্বাক্ষরের একটি পদ্ধতি রয়েছে । এটি অপ্রত্যাশিত আচরণের দিকে পরিচালিত করতে পারে এবং বেশ কয়েকবার আমাকে কঠোর কামড় দিয়েছে। ডিবাগ করার সময় "দেখা" এটি মুশকিল কারণ কারণ ফাংশনটি ফাইলের অন্যান্য ইন্টারফেস পদ্ধতির (সম্ভবত নীচে উল্লিখিত স্ব-ডকুমেন্টিং ইস্যু) উপস্থিত নেই is

  • একটি ইন্টারফেস থেকে একটি ফাংশন সরানো । সুস্পষ্টভাবে প্রয়োগকৃত পদ্ধতিগুলি হঠাৎ করে ডেড কোড হয়ে যাবে, তবে স্পষ্টতই প্রয়োগ করা পদ্ধতিগুলি সংকলনের ত্রুটির দ্বারা ধরা পড়বে। এমনকি ডেড কোডটি চারপাশে রাখা ভাল, আমি এটি পর্যালোচনা করতে এবং প্রচার করতে বাধ্য হতে চাই।

এটি দুর্ভাগ্যজনক যে সি # এর একটি কীওয়ার্ড নেই যা কোনও পদ্ধতিকে একটি অন্তর্নিহিত বাস্তবায়ন হিসাবে চিহ্নিত করতে বাধ্য করে, তাই সংকলক অতিরিক্ত চেক করতে পারে। ভার্চুয়াল পদ্ধতিতে 'ওভাররাইড' এবং 'নতুন' এর প্রয়োজনীয় ব্যবহারের কারণে উপরের সমস্যার কোনওটিই নেই।

দ্রষ্টব্য: স্থির বা খুব কমই পরিবর্তিত ইন্টারফেসের জন্য (সাধারণত বিক্রেতা এপিআই এর), এটি কোনও সমস্যা নয়। আমার নিজের ইন্টারফেসের জন্য, তবে তারা কখন / কীভাবে পরিবর্তিত হবে তা আমি অনুমান করতে পারি না can't

এটি স্ব-ডকুমেন্টিং

যদি আমি কোনও ক্লাসে 'পাবলিক বুল এক্সিকিউট ()' দেখি, তবে এটি কোনও ইন্টারফেসের অংশ বলে তা জানতে অতিরিক্ত কাজ করা যাচ্ছে take কাউকে সম্ভবত এটি বলার জন্য মন্তব্য করতে হবে, বা এটিকে অন্য কোনও ইন্টারফেস বাস্তবায়নের একটি গোষ্ঠীতে রাখতে হবে, সমস্তই একটি অঞ্চলের অধীনে বা "আইটিস্কের বাস্তবায়ন" বলে মন্তব্য করার গ্রুপিংয়ের অন্তর্ভুক্ত। অবশ্যই, এটি কেবল তখনই কাজ করে যদি গ্রুপ শিরোনামটি অফস্ক্রিন না করে ..

যেখানে: 'বুল আইটাস্ক.এক্সেকিউট ()' স্পষ্ট এবং দ্ব্যর্থহীন।

ইন্টারফেস বাস্তবায়ন পৃথক পৃথক

আমি ইন্টারফেসগুলিকে পাবলিক পদ্ধতির চেয়ে বেশি 'পাবলিক' বলে মনে করি কারণ তারা কংক্রিটের ধরণের পৃষ্ঠের ক্ষেত্রফলের কিছুটা অংশ উন্মুক্ত করার জন্য তৈরি করা হয়। এগুলি প্রকারভেদ, আচরণ, বৈশিষ্ট্য ইত্যাদির ধরনকে হ্রাস করে এবং প্রয়োগের ক্ষেত্রে, আমি মনে করি এই বিচ্ছেদটি রাখা কার্যকর useful

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

(আমি বুঝতে পারি যে পাবলিকগুলিও কোড চুক্তি, তবে ইন্টারফেসগুলি আরও শক্তিশালী হয়, বিশেষত একটি ইন্টারফেস-চালিত কোডবেসে যেখানে কংক্রিটের ধরণের সরাসরি ব্যবহার সাধারণত অভ্যন্তরীণ-কেবল কোডের লক্ষণ sign)

সম্পর্কিত: জোনের উপরোক্ত কারণ 2

ইত্যাদি

প্লাস এখানে অন্যান্য উত্তরে ইতিমধ্যে উল্লিখিত সুবিধাগুলি:

সমস্যা

এটা সব মজা এবং সুখ নয়। কিছু ঘটনা রয়েছে যেখানে আমি জড়িত থাকি:

  • মান ধরণের, কারণ এর জন্য বক্সিং এবং নিম্ন পারফের প্রয়োজন হবে। এটি কোনও কঠোর নিয়ম নয় এবং এটি ইন্টারফেস এবং এটি কীভাবে ব্যবহার করা হবে তা নির্ভর করে। IComparable? অন্তর্নিহিত। IFormattable? সম্ভবত সুস্পষ্ট।
  • তুচ্ছ সিস্টেম ইন্টারফেসগুলিতে এমন পদ্ধতি রয়েছে যা ঘন ঘন সরাসরি বলা হয় (যেমন আইডিস্পোজেবল is ডিসপোজ)।

এছাড়াও, আপনি যখন কংক্রিটের ধরণ রাখেন এবং একটি স্পষ্টত ইন্টারফেস পদ্ধতিতে কল করতে চান তখন ingালাই করতে ব্যথা হতে পারে। আমি দুটি পদ্ধতির একটিতে এটি মোকাবেলা করেছি:

  1. জনসাধারণ যুক্ত করুন এবং প্রয়োগের জন্য তাদের কাছে ইন্টারফেসের পদ্ধতিগুলি এগিয়ে রাখুন। সাধারণত অভ্যন্তরীণভাবে কাজ করার সময় সহজ ইন্টারফেসগুলির সাথে ঘটে।
  2. (আমার পছন্দসই পদ্ধতি) একটি যুক্ত করুন public IMyInterface I { get { return this; } }(যা অন্তর্ভুক্ত হওয়া উচিত) এবং কল করুন foo.I.InterfaceMethod()। যদি একাধিক ইন্টারফেসের এই দক্ষতার প্রয়োজন হয় তবে আমি ছাড়িয়ে এই নামটি প্রসারিত করুন (আমার অভিজ্ঞতাতে আমার এই প্রয়োজনটি বিরল)।

8

আপনি যদি স্পষ্টভাবে প্রয়োগ করেন তবে আপনি কেবল ইন্টারফেসের সদস্যদের একটি ইন্টারফেসের ধরণের রেফারেন্সের মাধ্যমে উল্লেখ করতে পারবেন। একটি রেফারেন্স যা বাস্তবায়নকারী শ্রেণীর ধরণ সেই ইন্টারফেস সদস্যদের প্রকাশ করবে না।

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

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

অসুবিধাটি, আমার মতে, আপনি হ'ল বাস্তবায়ন কোডটিতে ইন্টারফেসে / থেকে যেখানে নিজেকে জনসাধারণের সদস্যদের অ্যাক্সেস নেই তাতে আপনি নিজেরাই টাইপ করতে পারবেন।

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


1
সুন্দর উত্তর, বিল। অন্যান্য উত্তরগুলি দুর্দান্ত ছিল তবে আপনি কিছু অতিরিক্ত উদ্দেশ্যমূলক দৃষ্টিভঙ্গি সরবরাহ করেছেন (আপনার মতামতের শীর্ষে) যা আমার পক্ষে উপলব্ধি করা সহজ করে তোলে। বেশিরভাগ জিনিসের মতোই অন্তর্নিহিত বা সুস্পষ্ট বাস্তবায়নের সাথে কুশলী রয়েছে যাতে আপনার নির্দিষ্ট পরিস্থিতি বা ব্যবহারের ক্ষেত্রে আপনাকে কেবল সেরাটি ব্যবহার করতে হবে। আমি বলছি যারা উত্তরটি আরও ভালভাবে চেষ্টা করছেন তারা আপনার উত্তরটি পড়লে উপকৃত হবে।
ড্যানিয়েল

6

একটি অন্তর্নিহিত ইন্টারফেস বাস্তবায়ন হল যেখানে আপনার ইন্টারফেসের একই স্বাক্ষর সহ একটি পদ্ধতি রয়েছে।

একটি স্পষ্ট ইন্টারফেস বাস্তবায়ন হ'ল যেখানে আপনি স্পষ্টভাবে ঘোষণা করেন যে পদ্ধতিটি কোন ইন্টারফেসের অন্তর্ভুক্ত।

interface I1
{
    void implicitExample();
}

interface I2
{
    void explicitExample();
}


class C : I1, I2
{
    void implicitExample()
    {
        Console.WriteLine("I1.implicitExample()");
    }


    void I2.explicitExample()
    {
        Console.WriteLine("I2.explicitExample()");
    }
}

এমএসডিএন: অন্তর্নিহিত এবং স্পষ্টত ইন্টারফেস বাস্তবায়ন


6

ইন্টারফেস প্রয়োগকারী প্রতিটি শ্রেণীর সদস্য একটি ঘোষণার রফতানি করে যা ভিবি.এনইটি ইন্টারফেসের ঘোষণাপত্রগুলি যেমন রচনা হয় তেমন অর্থহীন similar

Public Overridable Function Foo() As Integer Implements IFoo.Foo

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

Protected Overridable Function IFoo_Foo() As Integer Implements IFoo.Foo

এই ক্ষেত্রে শ্রেণি এবং এর ডেরিভেটিভগুলি নামটি ব্যবহার করে কোনও শ্রেণীর সদস্য অ্যাক্সেসের অনুমতি দেওয়া হত IFoo_Foo, তবে বাইরের বিশ্ব কেবল নির্দিষ্ট সদস্যকে প্রবেশের মাধ্যমে প্রবেশ করতে সক্ষম হবে IFoo। এই ধরনের দৃষ্টিভঙ্গি প্রায়শই ভাল হয় যেখানে ইন্টারফেসের পদ্ধতিতে সমস্ত প্রয়োগের ক্ষেত্রে নির্দিষ্ট আচরণ থাকে তবে কেবলমাত্র কিছুতে কার্যকর আচরণ [যেমন কেবলমাত্র পঠন-পঠন সংগ্রহের IList<T>.Addপদ্ধতির জন্য নির্দিষ্ট আচরণটি নিক্ষেপ করা হয় NotSupportedException]। দুর্ভাগ্যক্রমে, সি # তে ইন্টারফেসটি কার্যকর করার একমাত্র সঠিক উপায় হ'ল:

int IFoo.Foo() { return IFoo_Foo(); }
protected virtual int IFoo_Foo() { ... real code goes here ... }

যেমন সুন্দর না।


2

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

সি # অভ্যন্তরীণ ইন্টারফেসে নিবন্ধে সমস্যা এবং সমাধানটি ভালভাবে ব্যাখ্যা করা হয়েছে ।

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


2

পূর্ববর্তী উত্তরগুলি ব্যাখ্যা করে যে কেন সি # তে একটি ইন্টারফেস সুস্পষ্টভাবে প্রয়োগ করা পছন্দনীয় হতে পারে (বেশিরভাগ আনুষ্ঠানিক কারণে)। যাইহোক, এক অবস্থা স্পষ্ট বাস্তবায়ন কোথায় বাধ্যতামূলক : অর্ডার এনক্যাপস্যুলেশন লিক যখন ইন্টারফেস অ- হয় এড়ানোর জন্য public, কিন্তু বাস্তবায়ন ক্লাস হয় public

// Given:
internal interface I { void M(); }

// Then explicit implementation correctly observes encapsulation of I:
// Both ((I)CExplicit).M and CExplicit.M are accessible only internally.
public class CExplicit: I { void I.M() { } }

// However, implicit implementation breaks encapsulation of I, because
// ((I)CImplicit).M is only accessible internally, while CImplicit.M is accessible publicly.
public class CImplicit: I { public void M() { } }

উপরের ফুটোটি অনিবার্য কারণ সি # স্পেসিফিকেশন অনুসারে , "সমস্ত ইন্টারফেস সদস্যদের স্পষ্টতই জনসাধারণের প্রবেশাধিকার রয়েছে।" ফলত, অন্তর্নিহিত বাস্তবায়নের এছাড়াও দিতে হবে public, অ্যাক্সেস এমনকি যদি ইন্টারফেস নিজেই যেমন হয় internal

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

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