উত্তরাধিকারের মাধ্যমে একটি এনাম বাড়ানো


88

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

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

আমি কোনও প্রদত্ত পদ্ধতি বাস্তবায়নে আগ্রহী নই, এটি আমার কৌতূহলকে উস্কে দেয় যখন এটি আমার কাছে ঘটে :-)


এটা কি তোমার প্রশ্নের উত্তর?
এনাম

উত্তর:


105

আপনি এনামগুলিকে প্রসারিত করতে না পারার কারণ এটি পলিমারফিজমে সমস্যা সৃষ্টি করে।

বলুন আপনার A, B এবং C এর মান সহ একটি এনাম রয়েছে and এবং এটি MyExtEnum হিসাবে D এর সাথে প্রসারিত করুন।

ধরুন কোনও পদ্ধতিটি কোথাও একটি myEnum মান আশা করে, উদাহরণস্বরূপ প্যারামিটার হিসাবে। একটি মাইেক্সটেনম মান সরবরাহ করা আইনী হওয়া উচিত, কারণ এটি একটি সাব টাইপ, কিন্তু এখন যখন আপনি ডিটিটি পরিণত হবে তখন আপনি কী করতে যাচ্ছেন?

এই সমস্যাটি দূর করতে, এনামগুলি বাড়ানো অবৈধ


4
আসলে, কারণটি কেবল এটির কোনও ধারণা নেই sense আপনি যে সমস্যার কথা উল্লেখ করেছেন, যেমন ক্লায়েন্ট কোডটি ধ্রুবক হিসাবে এটি প্রত্যাশা করে না তা গ্রহণ করে, বর্তমান বাস্তবায়ন সহ এখনও বিদ্যমান রয়েছে - বাস্তবে সংকলক আপনাকে switchকোনও defaultমামলা সরবরাহ বা ব্যতিক্রম ছুঁড়ে না দিয়ে এনাম মানগুলিতে ছাড় দেয় না । এবং এটি থাকলেও রানটাইমের সময় এনাম একটি পৃথক সংকলন থেকে আসতে পারে
রাফায়েল

@ রাফায়েল আমি কেবল এটি চেষ্টা করেছি, এবং কমপক্ষে জাভা 7-তে, আপনি কোনও defaultমামলা বা নিক্ষেপ ছাড়াই একটি এনাম চালু করতে পারেন ।
দাথন

@ দাথান আপনি নিশ্চয়ই ঠিক বলেছেন! যেমনটি লেখা হয়েছে, এটি কেবল ভুল - সম্ভবত আমার এটি সরিয়ে দেওয়া উচিত? আমি মামলার কথা ভাবছিলাম যখন আপনি switchপ্রয়োজনীয় মান প্রদানের জন্য যেমন স্থানীয় ব্যবহারের প্রাথমিক হিসাবে বা ব্যবহারের জন্য ব্যবহার করেনreturn
রাফায়েল

4
এটি ব্যক্তিগত নয়, রিক। তবে এটি এখন পর্যন্ত সবচেয়ে খারাপ কারণ! পলিমারফিজম এবং এনাম ...DayOfWeek a = (DayOfWeek) 1; DayOfWeek b = (DayOfWeek) 4711; Console.WriteLine(a + ", " + b);
বিটারব্লু

41

আপনি ভুল পথে যাচ্ছেন: এনামের একটি সাবক্লাসে কম এন্ট্রি থাকবে।

সিউডোকোডে, ভাবেন:

enum Animal { Mosquito, Dog, Cat };
enum Mammal : Animal { Dog, Cat };  // (not valid C#)

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

তবে না, সি # / জাভা উপ-এনামগুলিকে, এএএএফসিটি অনুমতি দেয় না, যদিও এটি অনেক সময় সত্যই কার্যকর হবে। এটি সম্ভবত কারণ তারা এনামগুলিকে অভ্যন্তরীণ চিহ্নগুলির পরিবর্তে (লিস্পের মতো) ইনট (সি এর মতো) হিসাবে প্রয়োগ করতে বেছে নিয়েছিল। (উপরে, (প্রাণী) 1 কী উপস্থাপন করে এবং (স্তন্যপায়ী) 1 কী উপস্থাপন করে এবং সেগুলি কি একই মান?)

যদিও আপনি নিজের এনাম-জাতীয় ক্লাস লিখতে পারেন (আলাদা নামের সাথে) যা এটি সরবরাহ করেছিল। সি # অ্যাট্রিবিউটগুলির সাথে এটি এমনকি একরকম সুন্দর দেখাচ্ছে।


4
আকর্ষণীয় বিশ্লেষণ। এভাবে কখনও ভাবিনি!
নার্ভ

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

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

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

এই উদাহরণটি সংশ্লেষিত এবং প্রমানিত হয় না যে বর্ধিত শ্রেণিতে কখনও কখনও আরও বেশি মান হওয়া উচিত নয়। এনাম VehicalParts {লাইসেন্স, গতি, ক্ষমতা}; এনাম কার্পার্টস {স্টিয়ারিং হুইল, উইনশিল্ড}; + যানবাহনের যা কিছু রয়েছে
বার্নোল্লি টিকটিক

41

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

public class Action {
    public string Name {get; private set;}
    public string Description {get; private set;}

    private Action(string name, string description) {
        Name = name;
        Description = description;
    }

    public static Action DoIt = new Action("Do it", "This does things");
    public static Action StopIt = new Action("Stop It", "This stops things");
}

তারপরে আপনি এটির মতো এনামের মতো আচরণ করতে পারেন:

public void ProcessAction(Action a) {
    Console.WriteLine("Performing action: " + a.Name)
    if (a == Action.DoIt) {
       // ... and so on
    }
}

কৌশলটি নিশ্চিত করা হয় যে নির্ধারকটি ব্যক্তিগত (বা আপনি উত্তরাধিকারী হতে চাইলে সুরক্ষিত) এবং আপনার উদাহরণগুলি স্থির।


আমি কোনও সি # ব্যক্তি নই, তবে আপনি কি সেখানে কিছুটা চূড়ান্ত (বা সিলড / কনস্ট / যা কিছু) চান না?
টম হাটিন -

4
আমি বিশ্বাস করি না। বা, অন্ততপক্ষে, আপনি এই শ্রেণীর কাছ থেকে নতুন "এনাম" মান যুক্ত করতে চান এমন পরিস্থিতিতে নয়। চূড়ান্ত এবং সিল করা উত্তরাধিকার আইআইআরসি প্রতিরোধ করে।
এস্তাসার

4
@ পূর্বের সিঁড়িগুলিতে আমি মনে করি তিনি ক্লাসের পরিবর্তে লাইনে যুক্ত finalকরার অর্থ public static Action DoIt = new Action("Do it", "This does things");দিয়েছিলেন।
ক্রাশ

4
যোগ করে হিসাবে readonly, আলা:public static readonly Action DoIt = new Action("Do it", "This does things");
এরিক

12

এনামগুলি সমস্ত সম্ভাব্য মানগুলির গণনার প্রতিনিধিত্ব করবে বলে মনে করা হয়, সুতরাং প্রসারিত করা ধারণাটির বিরুদ্ধে নয়।

তবে আপনি জাভাতে (এবং সম্ভবত সি ++ 0 এক্স) যা করতে পারেন তা এনুম ক্লাসের পরিবর্তে একটি ইন্টারফেস রয়েছে। তারপরে আপনাকে এমন একটি এনামে স্ট্যান্ডার্ড মান দেয় যা বৈশিষ্ট্যটি কার্যকর করে। অবশ্যই আপনি java.util.EnumSet এবং এর মতো ব্যবহার করতে পারবেন না don't এটি "আরও এনআইও বৈশিষ্ট্যসমূহ" এ গৃহীত পদ্ধতি, যা জেডিকে 7 এ হওয়া উচিত।

public interface Result {
    String name();
    String toString();
}
public enum StandardResults implements Result {
    TRUE, FALSE
}


public enum WTFResults implements Result {
    FILE_NOT_FOUND
}

4

আপনি রান-টাইমে বিদ্যমান এনাম থেকে লেবেল এবং মানগুলি পুনরুদ্ধার করতে .NET প্রতিবিম্ব ব্যবহার করতে পারেন ( Enum.GetNames()এবং Enum.GetValues()আপনি যে দুটি নির্দিষ্ট পদ্ধতি ব্যবহার করবেন) এবং তারপরে সেই উপাদানগুলির সাথে একটি নতুন তৈরি করতে কোড ইঞ্জেকশন ব্যবহার করুন এবং কিছু নতুন ব্যবহার করতে পারেন। এটি "বিদ্যমান এনাম থেকে উত্তরাধিকার সূত্রে" কিছুটা অ্যালগাউস বলে মনে হয়।


2

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

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


2

আপনি যদি বেস ক্লাস অর্থে প্রসারিত করতে চান তবে জাভাতে ... না no

তবে আপনি যদি অর্থ বলতে চান তবে বৈশিষ্ট্য এবং পদ্ধতিগুলি রাখার জন্য আপনি একটি এনাম মান বাড়িয়ে দিতে পারেন।

উদাহরণস্বরূপ, নিম্নলিখিতগুলি একটি বন্ধনী এনাম ব্যবহার করে:

class Person {
    enum Bracket {
        Low(0, 12000),
        Middle(12000, 60000),
        Upper(60000, 100000);

        private final int low;
        private final int high;
        Brackets(int low, int high) {
            this.low = low;
            this.high = high;
        }

        public int getLow() {
            return low;
        }

        public int getHigh() {
            return high;
        }

        public boolean isWithin(int value) {
           return value >= low && value <= high;
        }

        public String toString() {
            return "Bracket " + low + " to " + high;
        }
    }

    private Bracket bracket;
    private String name;

    public Person(String name, Bracket bracket) {
        this.bracket = bracket;
        this.name = name;
    }

    public String toString() {
        return name + " in " + bracket;
    }        
}

এটি NET- এ কোনও মান ধরণের (স্ট্রাক্ট) মতো লাগে। আমি জানতাম না যে আপনি জাভাতে এটি করতে পারেন।
এস্টোর

2

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

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



0

আপনি এর থেকে / একটি enum প্রসারিত আপনি ব্যবহার করতে পারেন অধিকারী হতে পারে না বৈশিষ্ট্যাবলী থেকে একটি বিবরণ ঘোষণা । আপনি যদি কোনও পূর্ণসংখ্যার মান খুঁজছেন তবে তা অন্তর্নির্মিত।


0

হুম্ম - যতদূর আমি জানি, এটি করা যায় না - অঙ্কগুলি নকশা-সময়ে লেখা হয় এবং প্রোগ্রামারটির সুবিধার্থে ব্যবহৃত হয়।

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


0

আমি সি # গণনায় মানগুলি যুক্ত করতে সক্ষম হতে চাই যা বিদ্যমান মানগুলির সংমিশ্রণ। উদাহরণস্বরূপ (এটি আমি করতে চাই):

অ্যাঙ্কারস্টাইলগুলি হিসাবে সংজ্ঞায়িত করা হয়

public enum AnchorStyles { None = 0, Top = 1, Bottom = 2, Left = 4, Right = 8, }

এবং আমি অ্যাঙ্কারস্টাইলস যুক্ত করতে চাই B নীচে রাইট = ডান + নীচে তাই বলার পরিবর্তে

my_ctrl.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;

আমি শুধু বলতে পারি

my_ctrl.Anchor = AnchorStyles.BottomRight;

এটি উপরে উল্লিখিত সমস্যাগুলির কোনও কারণ ঘটায় না, তাই এটি সম্ভব হলে ভাল হত।


0

কিছুকাল আগেও আমি এই জাতীয় কিছু করতে চেয়েছি এবং দেখেছি যে এনাম এক্সটেনশনগুলি প্রচুর মৌলিক ধারণাগুলিকে বাতিল করে দেবে ... (কেবল পলিমারফিসিম নয়)

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

public enum MyEnum { A = 1, B = 2, C = 4 }

public const MyEnum D = (MyEnum)(8);
public const MyEnum E = (MyEnum)(16);

func1{
    MyEnum EnumValue = D;

    switch (EnumValue){
      case D:  break;
      case E:  break;
      case MyEnum.A:  break;
      case MyEnum.B:  break;
   }
}

0

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

বিবেচনা:

 enum Person (JOHN SAM}   
 enum Student extends Person {HARVEY ROSS}

পলিমারফিজমের একটি সাধারণ ব্যবহারের ক্ষেত্রে হবে

 Person person = Student.ROSS;   //not legal

যা স্পষ্টতই ভুল।


0

একটি অস্থায়ী / স্থানীয় কাজ , যখন আপনি কেবল খুব স্থানীয় / এক সময় ব্যবহার করতে চান:

enum Animals { Dog, Cat }
enum AnimalsExt { Dog = Animals.Dog, Cat= Animals.Cat,  MyOther}
// BUT CAST THEM when using:
var xyz = AnimalsExt.Cat;
MethodThatNeedsAnimal(   (Animals)xyz   );

সমস্ত উত্তর এখানে দেখুন: এনাম "উত্তরাধিকার"

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