কেন সি # কোনও ইন্টারফেস প্রয়োগের জন্য স্থির পদ্ধতিগুলি মঞ্জুর করে না?


447

কেন সি # এইভাবে ডিজাইন করা হয়েছিল?

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

শ্রেণিগুলি যদি এই আচরণটি একটি ভাগ করা পদ্ধতিতে প্রয়োগ করতে চায় তবে তাদের কেন করা উচিত নয়?

আমার মনে কী আছে তার উদাহরণ এখানে:

// These items will be displayed in a list on the screen.
public interface IListItem {
  string ScreenName();
  ...
}

public class Animal: IListItem {
    // All animals will be called "Animal".
    public static string ScreenName() {
        return "Animal";
    }
....
}

public class Person: IListItem {

    private string name;

    // All persons will be called by their individual names.
    public string ScreenName() {
        return name;
    }

    ....

 }

6
ঠিক আছে, জাভা 8 এর এটি রয়েছে ( স্ট্যাকওভারফ্লো . com / জিজ্ঞাসা / 23148471/… )।
লিয়াং

1
উত্তরাধিকার বা ইন্টারফেস প্রয়োগের সাথে আপনি কীভাবে স্থিতিশীল আচরণকে একত্রিত করতে পারেন তা দেখুন: স্ট্যাকওভারফ্লো.
com/a/13567309

1
IListItem.ScreenName() => ScreenName()(সি # 7 সিনট্যাক্স ব্যবহার করে) স্থিতিশীল পদ্ধতিটি কল করে স্পষ্টভাবে ইন্টারফেস পদ্ধতিটি প্রয়োগ করবে। আপনি যখন উত্তরাধিকার যুক্ত করবেন তখন জিনিসগুলি কুশ্রী হয়ে ওঠে, যদিও (আপনাকে ইন্টারফেসটি পুনরায় প্রয়োগ করতে হবে)
জেরোইন মোস্টার্ট

2
সবাইকে জানিয়ে দেওয়া অপেক্ষা এখন শেষ! সি # 8.0 এর স্থিতিশীল ইন্টারফেস পদ্ধতি রয়েছে: ডটনেটফিডেল.না. / লার্জি 6 (যদিও তারা ওপি কীভাবে কাজ করতে চেয়েছিল তার থেকে কিছুটা আলাদাভাবে কাজ করে - আপনাকে সেগুলি বাস্তবায়ন করতে হবে না)
জেমি টেলস

উত্তর:


221

ধরে নিচ্ছি আপনি কেন এটি করতে পারবেন না তা জিজ্ঞাসা করছেন:

public interface IFoo {
    void Bar();
}

public class Foo: IFoo {
    public static void Bar() {}
}

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


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

public class Animal: IListItem {
    /* Can be tough to come up with a different, yet meaningful name!
     * A different casing convention, like Java has, would help here.
     */
    public const string AnimalScreenName = "Animal";
    public string ScreenName(){ return AnimalScreenName; }
}

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


6
একটি নিখুঁত উদাহরণ! তবে আমি নিশ্চিত নই যে আমি আপনার যুক্তি বুঝতে পেরেছি। অবশ্যই সংকলকটি স্থির সদস্যদেরও দেখার জন্য তৈরি করা যেতে পারে ? দৃষ্টান্তগুলির থিস পদ্ধতিগুলি বাস্তবায়নের জন্য ঠিকানাগুলির একটি সারণী নেই? স্থির পদ্ধতিগুলি এই টেবিলের মধ্যে অন্তর্ভুক্ত করা যায় না?
ক্রামি

12
এমন একটি কেস রয়েছে যেখানে এটি কার্যকর হতে পারে। উদাহরণস্বরূপ, আমি চাই সমস্ত প্রয়োগকারীরা গেটইনস্ট্যান্স পদ্ধতিটি প্রয়োগ করুন যা একটি XElement আর্গুমেন্ট গ্রহণ করে। আমি ইন্টারফেসে স্থির পদ্ধতি হিসাবে এটি সংজ্ঞায়িত করতে পারি না, বা ইন্টারফেস থেকে কোনও কনস্ট্রাক্টরের স্বাক্ষরের দাবিও করতে পারি না।
oleks

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

5
আপনি public static object MethodName(this IBaseClass base)স্থল শ্রেণীর মধ্যে যেমন: বেস ইন্টারফেসে এক্সটেনশন পদ্ধতি হিসাবে টুকরোটি সহজেই প্রয়োগ করতে পারেন । নেতিবাচক দিকটি হ'ল একটি ইন্টারফেস উত্তরাধিকারের মত নয় - এটি পৃথক উত্তরাধিকারীদেরকে পদ্ধতিটি ভালভাবে ওভাররাইড করতে বাধ্য করে না / অনুমতি দেয় না।
ট্রয় অ্যালফোর্ড

8
জেনারিক দিয়ে এটি প্রচুর পরিমাণে বোঝায়। উদাহরণস্বরূপ শূন্য কিছু <T> () যেখানে টি: ইসোমাইনটারফেস {নতুন টি () Do T.DoSomething2 (); }
ফ্রান্সিসকো রায়ান টলমাস্কি

173

আমার (সরলীকৃত) প্রযুক্তিগত কারণ হ'ল স্থির পদ্ধতিগুলি ভিটিবেলে নেই এবং সংকলনের সময় কল সাইটটি বেছে নেওয়া হয়েছে। এটি একই কারণে আপনার ওভাররাইড বা ভার্চুয়াল স্ট্যাটিক সদস্য থাকতে পারে না। আরও তথ্যের জন্য আপনার একটি সিএস গ্রেড বা সংকলক খুব দরকার - যার মধ্যে আমিও নই।

রাজনৈতিক কারণে, আমি এরিক লিপার্টকে উদ্ধৃত করব (যিনি সংকলক উইনক এবং তিনি ওয়াটারলু বিশ্ববিদ্যালয় থেকে গণিত, কম্পিউটার বিজ্ঞান এবং ফলিত গণিতের স্নাতক (উত্স: লিঙ্কডইন ) করেছেন:

... স্থিতিশীল পদ্ধতির মূল নকশার নীতি, সেই নীতি যা তাদের নাম দেয় ... [এটি] ... এটি সর্বদা নির্ধারণ করা যেতে পারে, সংকলনের সময়, কোন পদ্ধতিটি বলা হবে। অর্থাত্‍ কোডটি স্থির বিশ্লেষণের মাধ্যমে পদ্ধতিটি কেবল সমাধান করা যায়।

নোট করুন যে Lippert একটি তথাকথিত টাইপ পদ্ধতির জন্য ঘর ছেড়ে দেয়:

এটি হ'ল, কোনও ধরণের সাথে সম্পর্কিত (একটি স্ট্যাটিকের মতো) একটি পদ্ধতি, যা একটি অ-যুক্ত "এই" যুক্তিটি গ্রহণ করে না (উদাহরণস্বরূপ বা ভার্চুয়াল থেকে পৃথক), তবে যেখানে পদ্ধতিটি বলা হয় এটি টি (টির নির্মাণকৃত ধরণের উপর নির্ভর করে) ( স্ট্যাটিকের বিপরীতে যা সংকলনের সময় নির্ধারণযোগ্য হতে হবে)।

তবে এখনও এর কার্যকারিতা সম্পর্কে নিশ্চিত হওয়া যায়নি।


5
দুর্দান্ত, আমি এই উত্তরটি লিখতে চেয়েছিলাম - আমি কেবল প্রয়োগের বিস্তারিত জানতাম না।
ক্রিস মারাস্তি-জর্জি

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

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

2
প্রকৃতপক্ষে প্রশ্নের উত্তর দেওয়ার জন্য এবং পেডেন্টিক এবং অদ্ভুত না হওয়ার জন্য +1। যেমন আয়ান বয়েড বলেছিলেন: "এটি কোনও খারাপ নকশা নয় - এটি প্রযুক্তিগত সীমাবদ্ধতা" "
জোশুয়া পেচ

3
সম্পর্কিত ভেটেবলের সাথে একটি স্ট্যাটিক ক্লাসের জন্য কোনও অবজেক্ট তৈরি করা সম্পূর্ণভাবে সম্ভব। স্কালা কীভাবে পরিচালনা করে objectএবং কীভাবে তাদের ইন্টারফেস প্রয়োগ করার অনুমতি দেওয়া হয় তা দেখুন।
সেবাস্তিয়ান গ্রাফ

97

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

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

উদাহরণ স্বরূপ:

Repository GetRepository<T>()
{
  //need to call T.IsQueryable, but can't!!!
  //need to call T.RowCount
  //need to call T.DoSomeStaticMath(int param)
}

...
var r = GetRepository<Customer>()

দুর্ভাগ্যক্রমে, আমি কেবল "কুরুচিপূর্ণ" বিকল্প নিয়ে আসতে পারি:

  • প্রতিবিম্বটি কুশল ব্যবহার করুন এবং ইন্টারফেস এবং পলিমারফিজমের ধারণাটিকে মারধর করে।

  • সম্পূর্ণ আলাদা কারখানার ক্লাস তৈরি করুন

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

  • ইনস্ট্যান্ট করুন এবং তারপরে পছন্দসই ইন্টারফেস পদ্ধতিতে কল করুন

    জেনেরিক পরামিতি হিসাবে ব্যবহৃত ক্লাসগুলির উত্সটি নিয়ন্ত্রণ করি এমনকি এটি প্রয়োগ করা কঠিন হতে পারে। কারণটি হ'ল, উদাহরণস্বরূপ আমাদের কেবলমাত্র সুপরিচিত, "ডিবিতে সংযুক্ত" অবস্থায় থাকতে হবে।

উদাহরণ:

public class Customer 
{
  //create new customer
  public Customer(Transaction t) { ... }

  //open existing customer
  public Customer(Transaction t, int id) { ... }

  void SomeOtherMethod() 
  { 
    //do work...
  }
}

স্থির ইন্টারফেস সমস্যা সমাধানের জন্য তাত্ক্ষণিক ব্যবহার করার জন্য আমাদের নিম্নলিখিত জিনিসটি করা দরকার:

public class Customer: IDoSomeStaticMath
{
  //create new customer
  public Customer(Transaction t) { ... }

  //open existing customer
  public Customer(Transaction t, int id) { ... }

  //dummy instance
  public Customer() { IsDummy = true; }

  int DoSomeStaticMath(int a) { }

  void SomeOtherMethod() 
  { 
    if(!IsDummy) 
    {
      //do work...
    }
  }
}

এটি স্পষ্টতই কুৎসিত এবং অপ্রয়োজনীয় অন্যান্য সমস্ত পদ্ধতির কোডকে জটিল করে তোলে। স্পষ্টতই, মার্জিত সমাধানও নয়!


35
"এখানে বেশিরভাগ উত্তর পুরো পয়েন্টটি মিস করে miss" এর জন্য +1; এটি অবিশ্বাস্যরকম কীভাবে মনে হয় যে বেশিরভাগ

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

6
@ ক্রিস আমি একমত নই, প্রচুর ওভারকিল যখন আরও আর্কিটেকচারই 'সেরা' সমাধান হয় এটি সর্বদা একটি ভাষার ত্রুটির চিহ্ন। C # জেনেরিকস এবং বেনামে পদ্ধতি পেয়েছে বলে সমস্ত নিদর্শনগুলি আর কারও সম্পর্কে আলোচনা করে না?
mattmanser

3
আপনি কি "টি টি: আইকোয়্যারেবল, টি: আইডোসোমস্ট্যাটিক ম্যাথ" বা অনুরূপ ব্যবহার করতে পারবেন না?
রজার উইলককস

2
@ ক্রিসমারাস্তি-জর্জি: চারপাশে কিছুটা নোংরা কিন্তু আকর্ষণীয় উপায় হ'ল এই ছোট্ট নির্মাণ: public abstract class DBObject<T> where T : DBObject<T>, new()এবং তারপরে সমস্ত ডিবি ক্লাসকে উত্তরাধিকার সূত্রে পরিণত করুন DBObject<T>। তারপরে আপনি পুনঃসামগ্রী-দ্বারা কীটিকে অ্যাবস্ট্রাক্ট সুপারক্লাসে রিটার্ন টাইপ টি দিয়ে একটি স্ট্যাটিক ফাংশন করতে পারেন, সেই ফাংশনটি টি-এর একটি নতুন অবজেক্ট তৈরি করতে পারেন এবং তারপরে String GetRetrieveByKeyQuery()সেই বস্তুটিতে সুরক্ষিত (সুপারক্লাসে বিমূর্ত হিসাবে সংজ্ঞায়িত) কল করতে পারেন can কার্যকর করার জন্য আসল জিজ্ঞাসা। যদিও এটি সম্ভবত
সামান্যতম

20

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে এটি আকর্ষণীয়। উদাহরণটি সেরা নয়। আমি মনে করি আপনি কোনও ব্যবহারের কেস দেখালে এটি আরও পরিষ্কার হবে:

স্ট্রিং ডোসোমিংথিং <T> () যেখানে টি: আইসোম ফাংশন
{
  যদি (T.someFunction ())
    ...
}

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

  1. একটি স্ট্যাটিক জেনেরিক ক্লাস তৈরি করুন যার ধরণের পরামিতিটি সেই ধরণের হবে যা আপনি উপরের ডোসোমেটিংয়ে যাচ্ছেন। এই শ্রেণীর প্রতিটি পরিবর্তনের এক বা একাধিক স্থিতিশীল সদস্যের সাথে সেই ধরণের সম্পর্কিত স্টাফ থাকবে। এই তথ্যটি প্রতিটি শ্রেণীর আগ্রহের সাথে "রেজিস্টার ইনফরমেশন" রুটিন করে বা ক্লাস ভেরিয়েশনের স্থিতিশীল কন্সট্রাক্টর পরিচালিত হলে তথ্য পাওয়ার জন্য প্রতিবিম্ব ব্যবহার করে সরবরাহ করা যেতে পারে। আমি বিশ্বাস করি যে আধুনিক পদ্ধতিটি তুলনামূলক <টি> .ডাফল্ট () এর মতো জিনিস দ্বারা ব্যবহৃত হয়।
  2. প্রতিটি শ্রেণীর টি আগ্রহের জন্য, একটি শ্রেণি বা স্ট্রাক্ট সংজ্ঞায়িত করুন যা আইগাটওয়াসেসক্লাসআইনফো <টি> প্রয়োগ করে এবং "নতুন" সীমাবদ্ধাকে সন্তুষ্ট করে। শ্রেণিতে আসলে কোনও ক্ষেত্র থাকবে না, তবে এতে একটি স্থিতিশীল সম্পত্তি থাকবে যা ধরণের তথ্য সহ একটি স্ট্যাটিক ক্ষেত্র দেয় returns প্রশ্নটিতে জেনেরিক রুটিনে সেই শ্রেণীর বা স্ট্রাক্টের ধরণটি পাস করুন, যা একটি উদাহরণ তৈরি করতে সক্ষম হবে এবং অন্য শ্রেণীর তথ্য পেতে এটি ব্যবহার করতে সক্ষম হবে। আপনি যদি এই লক্ষ্যে কোনও ক্লাস ব্যবহার করেন তবে প্রতিবার নতুন বর্ণনাকারী-অবজেক্ট দৃষ্টান্তটি তৈরি করতে এড়াতে আপনার সম্ভবত উপরে বর্ণিত স্ট্যাটিক জেনেরিক ক্লাসটি সংজ্ঞায়িত করা উচিত। যদি আপনি কোনও কাঠামো ব্যবহার করেন তবে ইনস্ট্যান্টেশন ব্যয় শূন্য হওয়া উচিত, তবে প্রতিটি পৃথক স্ট্রাক্টের জন্য ডসোমিংং রুটিনের আলাদা সম্প্রসারণ প্রয়োজন।

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


16

স্বল্পদৃষ্টি, আমি অনুমান করব

যখন প্রাথমিকভাবে ডিজাইন করা হয়েছিল, ইন্টারফেসগুলি কেবল শ্রেণীর উদাহরণ সহ ব্যবহার করার উদ্দেশ্যে তৈরি হয়েছিল

IMyInterface val = GetObjectImplementingIMyInterface();
val.SomeThingDefinedinInterface();

এটি কেবল ইন্টারফেসগুলির সাথে পরিচয় করিয়ে দেওয়া হয়েছিল কারণ জেনারিকদের জন্য সীমাবদ্ধতাগুলির একটি ইন্টারফেসে একটি স্ট্যাটিক পদ্ধতি যুক্ত করা হয়েছিল যার ব্যবহারিক ব্যবহার রয়েছে।

(মন্তব্যে সাড়া দিয়ে :) আমি বিশ্বাস করি এখনই এটি পরিবর্তনের জন্য সিএলআর পরিবর্তনের প্রয়োজন হবে, যা বিদ্যমান অ্যাসেমব্লির সাথে অসম্পূর্ণতার দিকে নিয়ে যেতে পারে।


জেনেরিকের প্রসঙ্গে এটিই আমি প্রথম সমস্যার মুখোমুখি হয়েছিলাম, তবে আমি ভাবছি যদি ইন্টারফেসে স্থির পদ্ধতিগুলিও অন্যান্য প্রসঙ্গে কার্যকর হতে পারে? জিনিসগুলি পরিবর্তন করা যায়নি এমন কোনও কারণ আছে?
ক্রামি

আমি জেনেরিক ক্লাস প্রয়োগ করার সময় এটির মুখোমুখি হয়েছি যার জন্য কিছু পরামিতিগুলির সাথে নিজেকে তৈরি করার জন্য প্যারামিটার ধরণের প্রয়োজন। যেহেতু নতুন () কোনও নিতে পারে না। আপনি কী করে এখনও বুঝতে পারেন, ক্রমি?
টম 18

1
@ ক্রামি: স্ট্যাটিক এপিআইয়ের জন্য চুক্তি। আমি কোনও বস্তুর উদাহরণ চাই না, একটি নির্দিষ্ট স্বাক্ষরের কেবলমাত্র গ্যারান্টি, যেমন। আইম্যাট্রিক্স মাল্টিপ্লায়ার বা আইকুস্টমসারিয়ালাইজার। ক্লাসের সদস্যরা কৌশলটি সম্পাদন করায় ফানস্যাকস / অ্যাকশনস / প্রতিনিধিরা এই কৌশলটি সম্পাদন করে তবে আইএমও এটি কখনও কখনও অতিরিক্ত ব্যবহারের মতো বলে মনে হয় এবং এআইপিটি প্রসারিত করার জন্য অনভিজ্ঞদের জন্য বিভ্রান্তিকর হতে পারে।
ডেভিড কচিয়া

14

ইন্টারফেস একটি বস্তুর আচরণ নির্দিষ্ট করে।

স্থিতিশীল পদ্ধতি কোনও বস্তুর আচরণ নির্দিষ্ট করে না, তবে এমন আচরণ যা কোনও উপায়ে কোনও উপায়ে প্রভাবিত করে।


71
দুঃখিত .. আমি নিশ্চিত না যে এটা ঠিক! একটি ইন্টারফেস আচরণ নির্দিষ্ট করে না। একটি ইন্টারফেস নামকৃত ক্রিয়াকলাপগুলির একটি সেটকে সংজ্ঞায়িত করে। সম্পূর্ণ ভিন্ন উপায়ে আচরণ করার জন্য দুটি শ্রেণি একটি ইন্টারফেসের পদ্ধতি প্রয়োগ করতে পারে। সুতরাং, একটি ইন্টারফেস মোটেও আচরণ নির্দিষ্ট করে না। যে ক্লাসটি এটি প্রয়োগ করে।
স্কট ল্যাংহ্যাম

1
আশা করি আপনি ভাবেন না যে আমি বাছাই করছি .. তবে আমি মনে করি যে ওও শেখার জন্য কারও পক্ষে এটি গুরুত্বপূর্ণ পার্থক্য।
স্কট ল্যাংহ্যাম

4
একটি ইন্টারফেস আচরণ এবং উপস্থাপনা অন্তর্ভুক্ত একটি চুক্তি নির্দিষ্ট করার কথা। এজন্য উভয়কেই স্থির করার কথা বলে একটি ইন্টারফেস কলের আচরণ পরিবর্তন করা একটি নং। আপনার যদি এমন একটি ইন্টারফেস থাকে যেখানে কলটি ভিন্নভাবে কাজ করে (যেমন IList.Ad মুছে ফেলল) এটি সঠিক হবে না।
জেফ ইয়েটস

14
ঠিক আছে, হ্যাঁ, আপনি নিজের নামে অসম্পূর্ণ আচরণ করার একটি পদ্ধতি সংজ্ঞায়িত করার জন্য মাথার কাছে আবদ্ধ হবেন। যদিও আপনার যদি আইএলার্টস সার্ভিস.গেটঅ্যাসিস্ট্যান্স () থাকে তবে এর আচরণটি হতে পারে একটি হালকা ফ্ল্যাশ করা, একটি অ্যালার্ম বাজানো বা একটি কাঠি দিয়ে চোখে আঘাত করা।
স্কট ল্যাংহ্যাম

1
একটি বাস্তবায়ন একটি লগ ফাইল লিখতে সক্ষম হবে। এই আচরণটি ইন্টারফেসে নির্দিষ্ট করা হয়নি। তবে, আপনি ঠিক বলেছেন। 'সহায়তা' পাওয়ার আচরণকে সত্যই সম্মান করা উচিত।
স্কট ল্যাংহ্যাম

14

ইন্টারফেসগুলি "চুক্তিগুলি" উপস্থাপন করে এমন পরিমাণে, স্থির শ্রেণীর ইন্টারফেসগুলি প্রয়োগ করার পক্ষে এটি শান্ত যুক্তিযুক্ত বলে মনে হয়।

উপরোক্ত সমস্ত যুক্তি চুক্তির বিষয়ে এই পয়েন্টটি মিস করবে বলে মনে হচ্ছে।


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

@ সিমনমুরিয়ার এই ডকুমেন্টেশনটি আরও পরিষ্কারভাবে লেখা যেতে পারে তবে আপনি এটির ভুল ব্যাখ্যা করছেন। এটি আইকুস্টম মার্শালার ইন্টারফেস নয় যেটির জন্য getInstance স্থির পদ্ধতি প্রয়োজন। এটি [মার্শালএএস] কোড অ্যাট্রিবিউটের জন্য এটির প্রয়োজন। তারা বৈশিষ্ট্যটি সংযুক্ত মার্শেলারটির উদাহরণ পেতে অনুমতি দেওয়ার জন্য কারখানার প্যাটার্নটি ব্যবহার করছে। দুর্ভাগ্যক্রমে তারা মার্শালএস ডকুমেন্টেশন পৃষ্ঠায় গেটইনস্ট্যান্স প্রয়োজনীয়তার ডকুমেন্টিং অন্তর্ভুক্ত করতে সম্পূর্ণ ভুলে গেছে (এটি কেবল বিল্ট-ইন মার্শালিং বাস্তবায়ন ব্যবহার করে উদাহরণ দেখায়)।
স্কট গার্টনার

@ স্কটগার্টনার - আপনার বক্তব্যটি পাবেন না। msdn.microsoft.com/en-us/library/... স্পষ্টভাবে বলে: "ICustomMarshaler ইন্টারফেস বাস্তবায়ন ছাড়াও, কাস্টম marshalers একটি স্ট্যাটিক পদ্ধতি GetInstance নামক একটি প্যারামিটার হিসেবে স্ট্রিং গ্রহণ করে এবং ICustomMarshaler একটি রিটার্ন টাইপ হয়েছে বাস্তবায়ন করতে হবে এই। স্ট্যাটিক পদ্ধতিটি কাস্টম মার্শেলার একটি উদাহরণ ইনস্ট্যান্ট করার জন্য সাধারণ ভাষা রানটাইমের সিওএম ইন্টারপ স্তর দ্বারা ডাকা হয়। এটি অবশ্যই একটি স্থিতিশীল চুক্তির সংজ্ঞা।
সাইমন মাউরিয়ার

9

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

কীভাবে ফোন করবেন ??


public interface MyInterface { void MyMethod(); }
public class MyClass: MyInterface
{
    public static void MyMethod() { //Do Something; }
}

 // inside of some other class ...  
 // How would you call the method on the interface ???
    MyClass.MyMethod();  // this calls the method normally 
                         // not through the interface...

    // This next fails you can't cast a classname to a different type... 
    // Only instances can be Cast to a different type...
    MyInterface myItf = MyClass as MyInterface;  

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

একটি স্ট্যাটিক পদ্ধতিটি উদাহরণ থেকে কল করার অনুমতি দেওয়া হয়েছে et নেটও allowed এটি একটি পৃথক জিনিস। যদি কোনও স্থিতিশীল পদ্ধতি কোনও ইন্টারফেস প্রয়োগ করে, আপনি এটি উদাহরণ ছাড়াই কল করতে পারেন। এটি যা বোঝায় তা নয়। মনে রাখবেন আপনি কোনও ইন্টারফেসে বাস্তবায়ন রাখতে পারবেন না, এটি অবশ্যই শ্রেণিতে থাকতে হবে। সুতরাং যদি এই ইন্টারফেসটি বাস্তবায়নের জন্য পাঁচটি পৃথক শ্রেণি সংজ্ঞায়িত করা হয়, এবং প্রত্যেকটির এই স্থিতিশীল পদ্ধতিটির আলাদা প্রয়োগ রয়েছে, তবে সংকলকটি কোনটি ব্যবহার করবে?
চার্লস ব্রেটানা

1
জারিক্সের ক্ষেত্রে @ চার্লসব্রেটানা, এই ধরণের একটিটি পাস করেছে stat স্ট্যাটিক পদ্ধতিগুলির জন্য ইন্টারফেস রাখার ক্ষেত্রে আমি প্রচুর উপযোগিতা দেখছি (বা যদি আপনি চান, তবে তাদের "স্ট্যাটিক ইন্টারফেস" বলি এবং কোনও শ্রেণি উভয় স্থির ইন্টারফেস সংজ্ঞায়িত করার অনুমতি দেই এবং উদাহরণ ইন্টারফেস)। সুতরাং আমার যদি আমি Whatever<T>() where T:IMyStaticInterfaceকল করতে পারি Whatever<MyClass>()এবং কোনও উদাহরণের প্রয়োজন ছাড়াই বাস্তবায়নের T.MyStaticMethod()ভিতরে থাকতে পারি Whatever<T>()। কল করার পদ্ধতিটি রানটাইমে নির্ধারিত হবে। আপনি এটি প্রতিবিম্বের মাধ্যমে করতে পারেন, তবে বাধ্য করার মতো কোনও "চুক্তি" নেই।
জেএলসি

4

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

T SumElements<T>(T initVal, T[] values)
{
    foreach (var v in values)
    {
        initVal += v;
    }
}

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

সি # এর যা দরকার তা সত্যিকারের সীমাবদ্ধতার ধরণ, সমস্ত ইন্টারফেসও সীমাবদ্ধতা হতে পারে তবে সমস্ত সীমাবদ্ধতা ইন্টারফেস নয় তবে আপনি এটি করতে পারেন:

constraint CHasPlusEquals
{
    static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}

T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
    foreach (var v in values)
    {
        initVal += v;
    }
}

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


সি # তে অপারেটরগুলি স্থিতিশীল, তাই এটি এখনও বোঝায় না।
জন সাউন্ডার্স

মূল কথাটি, প্রতিবন্ধকতাটি যাচাই করে যে টিওয়াইপিই (উদাহরণ নয়) এর সাথে + অপারেটর রয়েছে (এবং এক্সটেনশান দ্বারা + = অপারেটর) এবং টেম্পলেটটি উত্পন্ন করার অনুমতি দেয়, তারপরে যখন আসল টেম্পলেট প্রতিস্থাপনটি বস্তুটি ব্যবহৃত হচ্ছে তার নিশ্চয়তা দেওয়া হয় এমন কোনও ধরণের যাটিতে অপারেটর রয়েছে (বা অন্যান্য স্থিতিশীল পদ্ধতি)) সুতরাং আপনি বলতে পারেন: SumElements <int> (0, 5); যা এটি তাত্পর্যপূর্ণ করবে: SumElements (int initVal, int [] মান) {foreach (মানগুলিতে var) {initVal + = v; }}, যা অবশ্যই নিখুঁত করে তোলে
জেরেমি সোরেনসেন

1
মনে রাখবেন এটি কোনও টেম্পলেট নয়। এটি জেনেরিক্স, যা সি ++ টেম্পলেটগুলির মতো নয়।
জন স্যান্ডার্স

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

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

3

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


3

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

এটি গুরুত্বপূর্ণ কিনা তা নিয়ে অফুরন্ত বিতর্ক থাকবে, যা সেরা অনুশীলন এবং এটি একভাবে বা অন্যভাবে সম্পাদন করার সমস্যা রয়েছে কিনা whether কেবল এটি সমর্থন না করে সি # আমাদের এটি সম্পর্কে উদ্বিগ্ন হওয়া থেকে বাঁচায়।

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


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

3

আপনি কোনও শ্রেণীর স্থিতিশীল পদ্ধতি এবং অ-স্থিতিশীল পদ্ধতিগুলি বিভিন্ন ইন্টারফেস হিসাবে ভাবতে পারেন। যখন ডাকা হয়, স্থির পদ্ধতিগুলি সিঙ্গেলটন স্ট্যাটিক শ্রেণীর অবজেক্টে সমাধান করে এবং অ স্থিতিক পদ্ধতিগুলি আপনি যে শ্রেণীর সাথে व्यवहार করেন তার উদাহরণ সমাধান করে to সুতরাং, আপনি যদি কোনও ইন্টারফেসে স্থিতিশীল এবং অ-স্থিতিশীল পদ্ধতি ব্যবহার করেন, আপনি যখন দুটি ইন্টারফেস কার্যকরভাবে ঘোষণা করতে চাইবেন যখন সত্যই আমরা চাই যে কোনও সংযুক্ত জিনিস অ্যাক্সেস করার জন্য ইন্টারফেসগুলি ব্যবহার করা হোক।


এটি একটি আকর্ষণীয় পিওভ এবং সম্ভবত সি # ডিজাইনারদের মনে এটি ছিল। আমি এখন থেকে স্থিতিশীল সদস্যদের সম্পর্কে অন্যভাবে ভাবব।
ক্রামি

3

ইন্টারফেস পদ্ধতিগুলির স্থিতিশীল প্রয়োগ বা মিস ব্র্যাককেট "তথাকথিত টাইপ পদ্ধতি" হিসাবে যেটি চালু করেছিলেন তা উদাহরণ দেওয়ার জন্য:

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

interface IDataRow {
  string GetDataSTructre();  // How to read data from the DB
  void Read(IDBDataRow);     // How to populate this datarow from DB data
}

public class DataTable<T> : List<T> where T : IDataRow {

  public string GetDataStructure()
    // Desired: Static or Type method:
    // return (T.GetDataStructure());
    // Required: Instantiate a new class:
    return (new T().GetDataStructure());
  }

}

প্রতিটি টেবিলটি পড়ার জন্য গেটডাটাস্ট্রাকচারটি একবারে প্রয়োজন, আরও একটি উদাহরণ ইনস্ট্যান্ট করার জন্য ওভারহেডটি ন্যূনতম। তবে, এখানে এই ক্ষেত্রে ভাল লাগবে be


1

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


1

ইন্টারফেসগুলি সংজ্ঞায়িত উপলব্ধ কার্যকারিতার বিমূর্ত সেট।

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

যদি পদ্ধতিগুলি স্থিতিশীল হিসাবে সংজ্ঞায়িত করা হয়, তবে ইন্টারফেসটি প্রয়োগকারী শ্রেণিটি যতটা পারে ঠিক তেমন এনক্যাপুলেটেড হবে না। অবজেক্ট অরিয়েন্টেড ডিজাইনের জন্য চেষ্টা করার জন্য এনক্যাপসুলেশন একটি ভাল জিনিস (আমি কেন এটিতে যাব না, আপনি এটি এখানে পড়তে পারেন: http://en.wikedia.org/wiki/Object-oriented )। এই কারণে ইন্টারফেসে স্থির পদ্ধতি অনুমোদিত নয়।


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

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

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

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

1

স্ট্যাটিক ক্লাসগুলি এটি করতে সক্ষম হওয়া উচিত যাতে তারা উদারভাবে ব্যবহার করতে পারে। পরিবর্তে কাঙ্ক্ষিত ফলাফলগুলি অর্জন করতে আমাকে একটি সিঙ্গলটন প্রয়োগ করতে হয়েছিল।

আমার কাছে স্ট্যাটিক বিজনেস লেয়ার ক্লাসগুলির একটি গুচ্ছ ছিল যা "ইউজার", "টিম", ইত্যাদি ইত্যাদির মতো প্রতিটি সত্তার জন্য "তৈরি", "পড়ুন", "আপডেট", "মুছুন" এর মতো সিআরইউডি পদ্ধতি প্রয়োগ করে ... তারপরে আমি একটি বেস তৈরি করেছি বিজনেস লেয়ার শ্রেণীর জন্য বিমূর্ত সম্পত্তি ছিল এমন নিয়ন্ত্রণ যা CRUD পদ্ধতি প্রয়োগ করে। এটি আমাকে বেস বর্গ থেকে "তৈরি করুন", "পড়ুন", "আপডেট", "মুছুন" অপারেশনগুলিকে স্বয়ংক্রিয় করার অনুমতি দেয়। স্ট্যাটিক সীমাবদ্ধতার কারণে আমাকে একটি সিঙ্গলটন ব্যবহার করতে হয়েছিল।


1

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


2
সমস্যাটি হ'ল এই প্রশ্নটি "ওওপি ইন" সম্পর্কে নয়। এটি "ইন সি #" সম্পর্কে। সি # তে কোনও "বার্তা" নেই।
জন স্যান্ডার্স

1

ঠিক আছে এখানে 'টাইপ পদ্ধতি' প্রয়োজনের একটি উদাহরণ is আমি কিছু উত্স এক্সএমএল ভিত্তিক ক্লাসের একটি সেট তৈরি করছি। সুতরাং আমি একটি আছে

  static public bool IsHandled(XElement xml)

ফাংশন যা প্রতিটি ক্লাস ঘুরে বলা হয়।

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

শ্রেণি প্রয়োগকারীরা এটি প্রয়োগ করতে বাধ্য করার জন্য এটি ইন্টারফেসে যুক্ত করা ভাল। এটি উল্লেখযোগ্য ওভারহেডের কারণ না ঘটায় - এটি কেবল একটি সংকলন / লিংক সময় চেক এবং ভিটিবেলকে প্রভাবিত করে না।

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

সুতরাং এটি একটি সামান্য সম্ভাব্য বৈশিষ্ট্য যা ভারসাম্য বজায় রাখার জন্য সম্ভবত সবচেয়ে ভাল।


1

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

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

স্ট্যাটিক ক্লাসগুলির সাথে ইন্টারফেসগুলি ব্যবহার করতে সক্ষম হওয়া এখানে একটি খুব স্পষ্ট উদাহরণ:

public interface ICrudModel<T, Tk>
{
    Boolean Create(T obj);
    T Retrieve(Tk key);
    Boolean Update(T obj);
    Boolean Delete(T obj);
}

বর্তমানে, আমি স্থিত ক্লাসগুলি লিখি যা কোনও পদ্ধতি যাচাই না করে এই পদ্ধতিগুলিকে ধারণ করে যে আমি কিছু ভুলে যাইনি। ওওপির আগে প্রোগ্রামিংয়ের খারাপ পুরানো দিনের মতো।


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

1

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

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


0

আমি মনে করি সংক্ষিপ্ত উত্তরটি "কারণ এটি শূন্য উপযোগের"। একটি ইন্টারফেস পদ্ধতিতে কল করতে আপনার টাইপের একটি উদাহরণ প্রয়োজন। উদাহরণ পদ্ধতি থেকে আপনি যে কোনও স্থিতিশীল পদ্ধতিতে কল করতে পারেন।


0

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

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

public interface IZeroWrapper<TNumber> {
  TNumber Zero {get;}
}

public class DoubleWrapper: IZeroWrapper<double> {
  public double Zero { get { return 0; } }
}

0

অবজেক্ট ওরিয়েন্টেড কনসেপ্ট অনুসারে ক্লাস দ্বারা প্রয়োগ করা ইন্টারফেস এবং অবজেক্ট ব্যবহার করে এই প্রয়োগকৃত ফাংশন (বা পদ্ধতি) অ্যাক্সেস করার চুক্তি রয়েছে।

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


0

ধারণাগতভাবে কোনও কারণ নেই যে কোনও ইন্টারফেস স্থির পদ্ধতিতে অন্তর্ভুক্ত এমন কোনও চুক্তি সংজ্ঞায়িত করতে পারে নি।

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

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

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


-1

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

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