টিএল; ডিআরএল খুব নীচে স্ক্রোল করুন।
আমি যা দেখছি তা থেকে আপনি সি # এর শীর্ষে একটি নতুন ভাষা প্রয়োগ করছেন। এনামগুলি একটি সনাক্তকারী (বা, যে কোনও নামের সাথে নতুন ভাষার উত্স কোডে প্রদর্শিত হয়) এর ধরণ বোঝায় বলে মনে হয়, যা প্রোগ্রামটির একটি গাছের উপস্থাপনায় যুক্ত নোডগুলিতে প্রয়োগ করা হবে বলে মনে হয়।
এই বিশেষ পরিস্থিতিতে নোডের বিভিন্ন ধরণের মধ্যে খুব কম পলিমারফিক আচরণ রয়েছে। অন্য কথায়, গাছের পক্ষে খুব আলাদা ধরণের (বৈকল্পিক) নোড থাকতে সক্ষম হওয়ার জন্য এই নোডগুলির প্রকৃত দর্শনটি মূলত যদি-তবে-অন্য শৃঙ্খলা (বা instanceof
/ is
চেকস) একটি দৈত্যের অবলম্বন করবে । এই দৈত্য চেকগুলি সম্ভবত প্রকল্পের বিভিন্ন স্থানে ঘটবে। এ কারণেই এনামগুলিকে সহায়ক বলে মনে হতে পারে, বা তারা কমপক্ষে instanceof
/ is
চেক হিসাবে সহায়ক ।
দর্শনার্থী প্যাটার্নটি এখনও কার্যকর হতে পারে। অন্য কথায়, এখানে বিভিন্ন কোডিং স্টাইল রয়েছে যা জায়ান্ট চেইনের পরিবর্তে ব্যবহার করা যেতে পারে instanceof
। তবে, আপনি যদি বিভিন্ন সুবিধাদি এবং ত্রুটিগুলি নিয়ে আলোচনা চান, তবে আপনি instanceof
প্রকল্পগুলির কূটনৈতিক শৃঙ্খলা থেকে এনামগুলি নিয়ে কোলাহল করার পরিবর্তে একটি কোড উদাহরণ প্রদর্শন করতে পছন্দ করেছেন ।
এটি ক্লাস এবং উত্তরাধিকারের স্তরক্রম কার্যকর নয় বলে নয় to পুরোপুরি বিপরীত. যদিও প্রতিটি ঘোষণার ধরণের জুড়ে কাজ করে এমন বহু বহুবর্ষী আচরণ নেই (প্রতিটি ঘোষণাপত্রের অবশ্যই Name
সম্পত্তি থাকতে হবে তা বাদ দিয়ে ), নিকটবর্তী ভাইবোনদের দ্বারা প্রচুর প্রচুর সমৃদ্ধ পলিমারফিক আচরণ রয়েছে। উদাহরণস্বরূপ, Function
এবং Procedure
সম্ভবত কিছু আচরণ ভাগ করুন (উভয় কলযোগ্য এবং টাইপ করা ইনপুট আর্গুমেন্টগুলির একটি তালিকা গ্রহণ করা), এবং PropertyGet
অবশ্যই Function
(উভয়ের একটি থাকার ReturnType
) থেকে আচরণের উত্তরাধিকারী হবে । আপনি যদি পরে-তে-অন্য শৃঙ্খলার জন্য এনাম বা উত্তরাধিকারের চেক ব্যবহার করতে পারেন তবে পলিমারফিক আচরণগুলি খণ্ডিত হলেও ক্লাসে অবশ্যই প্রয়োগ করা উচিত।
সেখানে অতিরিক্ত ব্যবহারের বিরুদ্ধে অনেক অনলাইন পরামর্শ করছি instanceof
/ is
চেক। পারফরম্যান্স অন্যতম কারণ নয়। বরং, কারণটি হ'ল প্রোগ্রামারকে জৈবিকভাবে উপযুক্ত পলিমারফিক আচরণগুলি আবিষ্কার করা থেকে বিরত রাখা, যেন instanceof
/ is
এটি ক্রাচ। তবে আপনার পরিস্থিতিতে আপনার অন্য কোনও পছন্দ নেই, কারণ এই নোডগুলির মধ্যে খুব কম মিল রয়েছে।
এখন এখানে কিছু কংক্রিট পরামর্শ দেওয়া হল।
পাতবিহীন গোষ্ঠীগুলির প্রতিনিধিত্ব করার বিভিন্ন উপায় রয়েছে।
আপনার মূল কোডটির নীচের অংশগুলি তুলনা করুন ...
[Flags]
public enum DeclarationType
{
Member = 1 << 7,
Procedure = 1 << 8 | Member,
Function = 1 << 9 | Member,
Property = 1 << 10 | Member,
PropertyGet = 1 << 11 | Property | Function,
PropertyLet = 1 << 12 | Property | Procedure,
PropertySet = 1 << 13 | Property | Procedure,
LibraryFunction = 1 << 23 | Function,
LibraryProcedure = 1 << 24 | Procedure,
}
এই পরিবর্তিত সংস্করণে:
[Flags]
public enum DeclarationType
{
Nothing = 0, // to facilitate bit testing
// Let's assume Member is not a concrete thing,
// which means it doesn't need its own bit
/* Member = 1 << 7, */
// Procedure and Function are concrete things; meanwhile
// they can still have sub-types.
Procedure = 1 << 8,
Function = 1 << 9,
Property = 1 << 10,
PropertyGet = 1 << 11,
PropertyLet = 1 << 12,
PropertySet = 1 << 13,
LibraryFunction = 1 << 23,
LibraryProcedure = 1 << 24,
// new
Procedures = Procedure | PropertyLet | PropertySet | LibraryProcedure,
Functions = Function | PropertyGet | LibraryFunction,
Properties = PropertyGet | PropertyLet | PropertySet,
Members = Procedures | Functions | Properties,
LibraryMembers = LibraryFunction | LibraryProcedure
}
এই পরিবর্তিত সংস্করণটি নন-কংক্রিট ঘোষণার ধরণের দিকে বিট বরাদ্দ এড়াতে পারে। পরিবর্তে, নন-কংক্রিট ঘোষণার ধরণের (ঘোষণার ধরণের বিমূর্ত গোষ্ঠীকরণের) এনাম মানগুলি রয়েছে যা এর সমস্ত শিশুদের মধ্যে বিটওয়াইস-বা (বিটের ইউনিয়ন)।
একটি সতর্কবাণী রয়েছে: যদি কোনও বিমূর্ত ঘোষণার প্রকার থাকে যার একটি একা সন্তান থাকে এবং যদি কংক্রিটের (সন্তানের) থেকে বিমূর্ত একটি (পিতামাতার) মধ্যে পার্থক্য করার প্রয়োজন হয়, তবে বিমূর্তটির এখনও তার নিজস্ব বিটের প্রয়োজন হবে ।
এই প্রশ্নের সাথে সুনির্দিষ্ট একটি সতর্কতা: একটি Property
প্রাথমিকভাবে একটি সনাক্তকারী (যখন আপনি কোডটিতে এটি কীভাবে ব্যবহৃত হয় তা না দেখেই কেবল তার নামটি দেখেন), তবে এটি কীভাবে ব্যবহৃত হচ্ছে তা দেখলেই এটি PropertyGet
/ PropertyLet
/ এ সংক্রমণিত হতে পারে PropertySet
কোডে অন্য কথায়, পার্সিংয়ের বিভিন্ন পর্যায়ে আপনাকে একটি Property
সনাক্তকারী চিহ্নিত করতে হবে "এই নামটি কোনও সম্পত্তিকে বোঝায়" এবং পরে পরিবর্তন করতে হবে "কোডের এই লাইনটি একটি নির্দিষ্ট উপায়ে এই সম্পত্তিটি অ্যাক্সেস করছে"।
এই সতর্কতামূলক সমাধানের জন্য আপনার দুটি সেট এনামের প্রয়োজন হতে পারে; একটি এনাম একটি নাম (সনাক্তকারী) কী তা বোঝায়; অন্য এনাম কোডটি কী করার চেষ্টা করছে তা বোঝায় (উদাহরণস্বরূপ কোনও কিছুর মূল অংশ ঘোষণা করা; নির্দিষ্ট উপায়ে কিছু ব্যবহার করার চেষ্টা করা)।
প্রতিটি এনাম মান সম্পর্কে সহায়ক তথ্য পরিবর্তে একটি অ্যারের থেকে পড়া যায় কিনা তা বিবেচনা করুন।
এই পরামর্শটি অন্যান্য পরামর্শগুলির সাথে পারস্পরিকভাবে একচেটিয়া কারণ এর জন্য দুটি পাওয়ার মানকে ছোট অ-নেতিবাচক পূর্ণসংখ্যার মানগুলিতে রূপান্তর করতে হবে।
public enum DeclarationType
{
Procedure = 8,
Function = 9,
Property = 10,
PropertyGet = 11,
PropertyLet = 12,
PropertySet = 13,
LibraryFunction = 23,
LibraryProcedure = 24,
}
static readonly bool[] DeclarationTypeIsMember = new bool[32]
{
?, ?, ?, ?, ?, ?, ?, ?, // bit[0] ... bit[7]
true, true, true, true, true, true, ?, ?, // bit[8] ... bit[15]
?, ?, ?, ?, ?, ?, ?, true, // bit[16] ... bit[23]
true, ... // bit[24] ...
}
static bool IsMember(DeclarationType dt)
{
int intValue = (int)dt;
return (intValue < 0 || intValue >= 32) ? false : DeclarationTypeIsMember[intValue];
// you can also throw an exception if the enum is outside range.
}
// likewise for IsFunction(dt), IsProcedure(dt), IsProperty(dt), ...
রক্ষণাবেক্ষণ সমস্যা হতে চলেছে।
সি # ধরণের (উত্তরাধিকারের শ্রেণিবিন্যাসের ক্লাস) এবং আপনার এনাম মানগুলির মধ্যে এক থেকে একের ম্যাপিং কিনা তা পরীক্ষা করুন।
(বিকল্পভাবে, এক প্রকারের সাথে এক থেকে এক ম্যাপিং নিশ্চিত করার জন্য আপনি আপনার এনাম মানগুলিকে টুইঙ্ক করতে পারেন))
সি # তে, অনেকগুলি লাইব্রেরি Type object.GetType()
ভাল বা খারাপের জন্য নিফটি পদ্ধতিটি অপব্যবহার করে ।
আপনি যে কোনও জায়গায় এনামকে মান হিসাবে সংরক্ষণ করছেন, আপনি নিজেকে জিজ্ঞাসা করতে পারেন যে আপনি Type
পরিবর্তে কোনও মান হিসাবে সঞ্চয় করতে পারবেন কিনা ।
এই কৌশলটি ব্যবহার করতে, আপনি দুটি পঠনযোগ্য হ্যাশ টেবিল শুরু করতে পারেন, যথা:
// For disambiguation, I'll assume that the actual
// (behavior-implementing) classes are under the
// "Lang" namespace.
static readonly Dictionary<Type, DeclarationType> TypeToDeclEnum = ...
{
{ typeof(Lang.Procedure), DeclarationType.Procedure },
{ typeof(Lang.Function), DeclarationType.Function },
{ typeof(Lang.Property), DeclarationType.Property },
...
};
static readonly Dictionary<DeclarationType, Type> DeclEnumToType = ...
{
// same as the first dictionary;
// just swap the key and the value
...
};
যারা ক্লাস এবং উত্তরাধিকারের শ্রেণিবিন্যাসের পরামর্শ দিচ্ছেন তাদের জন্য চূড়ান্ত প্রতিপত্তি ...
একবার আপনি দেখতে পাচ্ছেন যে এনামগুলি উত্তরাধিকারের শ্রেণিবিন্যাসের একটি অনুমান , নীচের পরামর্শটি ধারণ করে:
- প্রথমে আপনার উত্তরাধিকারের স্তরক্রম ডিজাইন করুন (বা উন্নত করুন),
- তারপরে ফিরে যান এবং আপনার এনামগুলিকে আনুমানিক সেই উত্তরাধিকারক্রমক্রম অনুসারে ডিজাইন করুন।
DeclarationType
। আমি কিনা তা নির্ধারণ করতে বা না চানx
একটি উপপ্রকার হয়y
, আমি সম্ভবত সেই লিখতে যেমন চান যাচ্ছিx.IsSubtypeOf(y)
, যেমন নাx && y == y
।