একটি ডাটাবেস অনুসন্ধান সারণীতে মানগুলির উপর ভিত্তি করে একটি এনুম স্বয়ংক্রিয়ভাবে তৈরি করবেন?


116

আমি কীভাবে স্বয়ংক্রিয়ভাবে একটি এনাম তৈরি করব এবং পরবর্তীকালে ডাটাবেস অনুসন্ধান সারণীতে (এন্টারপ্রাইজ লাইব্রেরির ডেটা স্তর ব্যবহার করে) মানগুলির উপর ভিত্তি করে সি # তে এর মানগুলি ব্যবহার করব?

উদাহরণস্বরূপ, আমি যদি ডাটাবেসে একটি নতুন অনুসন্ধান মান যুক্ত করি তবে আমি কোডে অতিরিক্ত স্ট্যাটিক এনাম মান ঘোষণার ম্যানুয়ালি যুক্ত করতে চাই না - আমি এনামকে ডাটাবেসের সাথে সিঙ্ক করে রাখতে চাই।

এরকম কিছু আছে কি?


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


এটি কী সম্ভব যে আপনি আরও ভাল সমাধানের উপায়ে এমন একটি উপাখ্যান ব্যবহার করার চেষ্টা করছেন?
ড্যান

আমি @ ড্যানের সাথে আছি, এটি করার আরও ভাল উপায় থাকতে হবে।
এন_এ

@mydogisbox আরও ভাল উপায় কি?
ইরান otzap

@ ইরানোটজার আসলে, কিছুটা চিন্তা করার পরে, প্রাক-বিল্ড পদক্ষেপটি লিখতে হবে যা
ডিবিকে

1
বলা হচ্ছে, "আমি কোনও কোড তৈরি করতে চাই না স্ট্যাটিক এনাম তৈরি করতে চাই না" তার অর্থ কী তা আমি নিশ্চিত নই, তাই সম্ভবত এটি প্রয়োজনীয়তার সাথে খাপ খায় না।
এন_এ

উত্তর:


97

আমি ঠিক এই জিনিস করছি, কিন্তু আপনি প্রয়োজন এটির জন্য কাজ করতে কোড নির্মাণ কিছু না।

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

এনাম জেনারেশন কোডটি এরকম:

// Get the current application domain for the current thread
AppDomain currentDomain = AppDomain.CurrentDomain;

// Create a dynamic assembly in the current application domain,
// and allow it to be executed and saved to disk.
AssemblyName name = new AssemblyName("MyEnums");
AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name,
                                      AssemblyBuilderAccess.RunAndSave);

// Define a dynamic module in "MyEnums" assembly.
// For a single-module assembly, the module has the same name as the assembly.
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name.Name,
                                  name.Name + ".dll");

// Define a public enumeration with the name "MyEnum" and an underlying type of Integer.
EnumBuilder myEnum = moduleBuilder.DefineEnum("EnumeratedTypes.MyEnum",
                         TypeAttributes.Public, typeof(int));

// Get data from database
MyDataAdapter someAdapter = new MyDataAdapter();
MyDataSet.MyDataTable myData = myDataAdapter.GetMyData();

foreach (MyDataSet.MyDataRow row in myData.Rows)
{
    myEnum.DefineLiteral(row.Name, row.Key);
}

// Create the enum
myEnum.CreateType();

// Finally, save the assembly
assemblyBuilder.Save(name.Name + ".dll");

সমাধানে আমার অন্যান্য প্রকল্পগুলি এই উত্পন্ন সমাবেশটি উল্লেখ করে। ফলস্বরূপ, আমি তখন কোডে গতিশীল এনামগুলি ব্যবহার করতে পারি, ইন্টেলিজেন্স সহ সম্পূর্ণ।

তারপরে, আমি একটি বিল্ড-পরবর্তী ইভেন্ট যুক্ত করেছি যাতে এই "এনিউমেটেড টাইপস" প্রকল্পটি তৈরি হওয়ার পরে এটি নিজেই চালিত হয় এবং "মাইএনমস.ডিএলএল" ফাইল উত্পন্ন করে।

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

আমি এই এমএসডিএন নিবন্ধ থেকে উপরের কোডটির বেশিরভাগটি পেয়েছি ।

আশাকরি এটা সাহায্য করবে!


7
যারা পোস্ট-বিল্ডে ফলাফল নির্বাহযোগ্য চালাতে জানেন না তাদের জন্য: 1) প্রকল্পটিতে ডান ক্লিক করুন 2) বৈশিষ্ট্যগুলিতে ক্লিক করুন 3) বিল্ড ইভেন্টগুলি ক্লিক করুন 4) "পোস্ট-বিল্ড ইভেন্ট কমান্ড লাইনগুলি" পাঠ্য বাক্সে টাইপ করুন Tar (টার্গেটপথ)
মিগুয়েল

এই লিঙ্কে উল্লিখিত কাস্টম অ্যাট্রিবিউট সংজ্ঞা দিয়ে ডায়নামিক এনাম করা কি সম্ভব ?
বালাগুরুনাথন মেরিমুথু

49

সংকলনের সময় এনামগুলি অবশ্যই নির্দিষ্ট করতে হবে, আপনি রান-টাইমের সময় গতিময়ভাবে এনামগুলি যুক্ত করতে পারবেন না - এবং আপনি কেন কোডটিতে তাদের কোনও ব্যবহার / রেফারেন্স পাবেন না?

পেশাদার সি # ২০০৮ থেকে:

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

সুতরাং, আমি নিশ্চিত নই যে আপনি এনামগুলি যেভাবে চান ব্যবহার করতে পারবেন।


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

14
পোস্টার এবং 18 টি আপভেস্ট কিন্ডা তার বক্তব্য মিস করেছেন। দেখে মনে হচ্ছে তিনি রানটাইম ডায়নামিক এনামগুলি নয়, জেনারেটেড এনামগুলি চান ।
ম্যাট মিচেল

+1 টি। একটি এনাম মূলত পূর্ণসংখ্যার ধ্রুবকগুলি সংজ্ঞায়নের অন্য উপায় (এমনকি System.Enumকিছু অতিরিক্ত কার্যকারিতা থাকলেও )। লেখার পরিবর্তে const int Red=0, Green=1, Blue=3;আপনি লিখুন enum { Red, Green, Blue }। একটি ধ্রুবক সংজ্ঞা দ্বারা ধ্রুবক এবং গতিশীল নয়।
অলিভিয়ার জ্যাকট-ডেসকোম্বেস

2
@ অলিভার যদি আপনি শব্দার্থবিজ্ঞানের পক্ষে তর্ক করতে চান তবে হ্যাঁ, আপনি সঠিক। তবে আমি গ্রাফেইনের মন্তব্যটির সাথে একমত - আমার বিশ্বাস ওপি উত্পন্ন এনামগুলি খুঁজছে । তিনি চান যে এনাম মানগুলি ডাটাবেস থেকে আসে এবং সেগুলি হার্ড-কোড না করে।
প্যান্ডিনকাস

1
বা ... আমি বলি যে আমি আমার ওয়েবকনফাইগের কাউকে আমার ইমেল টেম্প্লেটিং কোডের জন্য ইমেল টেম্পলেটগুলির জন্য টোকেন ধরণের সংজ্ঞা দিই allow এটি ভাল লাগবে যদি আমার বিদ্যমান এনামগুলি ইমেল টোকেন্স নামে পরিচিত যা এই স্ট্রিং প্রকারগুলিকে উপস্থাপন করে তা আমার ওয়েবকনফাইগে সংজ্ঞায়িত types প্রকারের ভিত্তিতে জিন করা হবে be সুতরাং যদি কেউ আমার মূল মান যেমন "ইমেল, এফএন নাম" এর মাধ্যমে ওয়েবকনফাইগে একটি নতুন ইমেল টোকেন যুক্ত করে এবং আমার ইতিমধ্যে একটি এনাম রয়েছে যে আমি এই টোকেনগুলি যেমন ইমেলটেম্পলেটটি উপস্থাপন করতে যাচ্ছি তবে ইমেলটি যদি কেউ ঠিক করতে পারত তবে ভাল হত would একটি নতুন স্ট্রিং web.config যে কী তে টোকেন যোগ করুন এবং আমার enum স্বয়ংক্রিয়ভাবে const যোগ হবে
PositiveGuy

18

এটি একটি বাস্তব enum হতে হবে? Dictionary<string,int>পরিবর্তে ব্যবহার সম্পর্কে কীভাবে ?

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

Dictionary<string, int> MyEnum = new Dictionary(){{"One", 1}, {"Two", 2}};
Console.WriteLine(MyEnum["One"]);

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

1
আমি রাজী. তবে মনে রাখবেন ভুল সময়যুক্ত স্ট্রিং রানটাইমের সময় ধরা পড়বে। সমস্ত এনাম সদস্যদের কভার করার জন্য কেবল একটি পরীক্ষার কেস যুক্ত করুন।
অটোডিডেক্ট

1
আপনি যদি আক্ষরিক পরিবর্তে ধ্রুবক ব্যবহার করেন তবে ভুল টাইপ করা কোনও সমস্যা নয়
মাসলো

@ ম্যাসলো ধরে নিন আপনার অর্থ এনামস, স্ট্রিং ধ্রুবক নয়।
ম্যাট মিশেল

4
+1 টি। একটি অভিধান বা হ্যাশসেট ব্যবহার করা গতিশীল এনাম হতে পারে তার নিকটে আসে। সম্পূর্ণ গতিশীল মানে এটি রানটাইমের সময় ঘটে এবং তাই ত্রুটি যাচাইয়ের সময় রানটাইমের সময় ঘটতে হবে।
অলিভিয়ার জ্যাকট-ডেসকোম্বেস

13

আমি এটি দিয়ে করেছি টি 4 টেমপ্লেট । আপনার প্রকল্পে একটি .tt ফাইল ফেলে দেওয়া, এবং প্রাক-বিল্ডিং পদক্ষেপ হিসাবে টি 4 টেমপ্লেট চালানোর জন্য ভিজ্যুয়াল স্টুডিও সেট আপ করা মোটামুটি তুচ্ছ।

টি 4 একটি .cs ফাইল উত্পন্ন করে, যার অর্থ আপনি এটি কেবল ডাটাবেসটিকে জিজ্ঞাসা করতে পারেন এবং ফলাফল থেকে .cs ফাইলটিতে একটি এনাম তৈরি করতে পারেন। প্রাক-বিল্ড টাস্ক হিসাবে বিরক্ত, এটি প্রতিটি বিল্ডে আপনার এনামটি পুনরায় তৈরি করবে, বা আপনি প্রয়োজন অনুযায়ী টি 4 নিজেই চালাতে পারবেন।


12

ধরা যাক আপনার ডিবিতে আপনার নিম্নলিখিত রয়েছে:

table enums
-----------------
| id | name     |
-----------------
| 0  | MyEnum   |
| 1  | YourEnum |
-----------------

table enum_values
----------------------------------
| id | enums_id | value | key    |
----------------------------------
| 0  | 0        | 0     | Apple  |
| 1  | 0        | 1     | Banana |
| 2  | 0        | 2     | Pear   |
| 3  | 0        | 3     | Cherry |
| 4  | 1        | 0     | Red    |
| 5  | 1        | 1     | Green  |
| 6  | 1        | 2     | Yellow |
----------------------------------

আপনার প্রয়োজনীয় মানগুলি পেতে একটি নির্বাচন করুন:

select * from enums e inner join enum_values ev on ev.enums_id=e.id where e.id=0

এনামের জন্য উত্স কোডটি তৈরি করুন এবং আপনি এর মতো কিছু পাবেন:

String enumSourceCode = "enum " + enumName + "{" + enumKey1 + "=" enumValue1 + "," + enumKey2 + ... + "}";

(স্পষ্টতই এটি কোনও ধরণের লুপে নির্মিত হয়েছে))

তারপরে মজার অংশটি আসে, আপনার এনামগুলি সংকলন করে এবং এটি ব্যবহার করে:

CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cs = new CompilerParameters();
cp.GenerateInMemory = True;

CompilerResult result = provider.CompileAssemblyFromSource(cp, enumSourceCode);

Type enumType = result.CompiledAssembly.GetType(enumName);

এখন আপনার কাছে টাইপটি সংকলিত এবং ব্যবহারের জন্য প্রস্তুত।
ডিবিতে সঞ্চিত এনাম মান পেতে আপনি ব্যবহার করতে পারেন:

[Enum].Parse(enumType, value);

যেখানে মান হয় পূর্ণসংখ্যার মান (0, 1, ইত্যাদি) বা এনাম পাঠ্য / কী (অ্যাপল, কলা ইত্যাদি) হতে পারে


4
আসলে কীভাবে এটি সাহায্য করবে? কোনও ধরণের সুরক্ষা এবং কোনও ইন্টেলিজেন্স নেই। মূলত এটি একটি ধ্রুবক ব্যবহারের আরও জটিল উপায় যেহেতু তাকে যেভাবেই মান প্রদান করতে হয়।
রুনবার্গ

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

10

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

সুতরাং এখানে টেবিলের জন্য ডিডিএল এসকিউএল রয়েছে:

USE [ocms_dev]
    GO

CREATE TABLE [dbo].[Role](
    [RoleId] [int] IDENTITY(1,1) NOT NULL,
    [RoleName] [varchar](50) NULL
) ON [PRIMARY]

সুতরাং এখানে কনসোল প্রোগ্রামটি dll উত্পাদন করছে:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Data.Common;
using System.Data;
using System.Data.SqlClient;

namespace DynamicEnums
{
    class EnumCreator
    {
        // after running for first time rename this method to Main1
        static void Main ()
        {
            string strAssemblyName = "MyEnums";
            bool flagFileExists = System.IO.File.Exists (
                   AppDomain.CurrentDomain.SetupInformation.ApplicationBase + 
                   strAssemblyName + ".dll"
            );

            // Get the current application domain for the current thread
            AppDomain currentDomain = AppDomain.CurrentDomain;

            // Create a dynamic assembly in the current application domain,
            // and allow it to be executed and saved to disk.
            AssemblyName name = new AssemblyName ( strAssemblyName );
            AssemblyBuilder assemblyBuilder = 
                    currentDomain.DefineDynamicAssembly ( name,
                            AssemblyBuilderAccess.RunAndSave );

            // Define a dynamic module in "MyEnums" assembly.
            // For a single-module assembly, the module has the same name as
            // the assembly.
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule (
                    name.Name, name.Name + ".dll" );

            // Define a public enumeration with the name "MyEnum" and
            // an underlying type of Integer.
            EnumBuilder myEnum = moduleBuilder.DefineEnum (
                    "EnumeratedTypes.MyEnum",
                    TypeAttributes.Public,
                    typeof ( int )
            );

            #region GetTheDataFromTheDatabase
            DataTable tableData = new DataTable ( "enumSourceDataTable" );

            string connectionString = "Integrated Security=SSPI;Persist " +
                    "Security Info=False;Initial Catalog=ocms_dev;Data " +
                    "Source=ysg";

            using (SqlConnection connection = 
                    new SqlConnection ( connectionString ))
            {

                SqlCommand command = connection.CreateCommand ();
                command.CommandText = string.Format ( "SELECT [RoleId], " + 
                        "[RoleName] FROM [ocms_dev].[dbo].[Role]" );

                Console.WriteLine ( "command.CommandText is " + 
                        command.CommandText );

                connection.Open ();
                tableData.Load ( command.ExecuteReader ( 
                        CommandBehavior.CloseConnection
                ) );
            } //eof using

            foreach (DataRow dr in tableData.Rows)
            {
                myEnum.DefineLiteral ( dr[1].ToString (),
                        Convert.ToInt32 ( dr[0].ToString () ) );
            }
            #endregion GetTheDataFromTheDatabase

            // Create the enum
            myEnum.CreateType ();

            // Finally, save the assembly
            assemblyBuilder.Save ( name.Name + ".dll" );
        } //eof Main 
    } //eof Program
} //eof namespace 

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

// add the reference to the newly generated dll
use MyEnums ; 

class Program
{
    static void Main ()
    {
        Array values = Enum.GetValues ( typeof ( EnumeratedTypes.MyEnum ) );

        foreach (EnumeratedTypes.MyEnum val in values)
        {
            Console.WriteLine ( String.Format ( "{0}: {1}",
                    Enum.GetName ( typeof ( EnumeratedTypes.MyEnum ), val ),
                    val ) );
        }

        Console.WriteLine ( "Hit enter to exit " );
        Console.ReadLine ();
    } //eof Main 
} //eof Program

1
@ ইয়র্ডান জর্জিভ -আপনার flagFileExistsঅন্য কোথাও এটি ব্যবহার করা হয় না কেন আপনি ঘোষণা করেন?
মাইকেল কিনিস্কারন

2
আমার ধারণা এটি তুলনায় একটি বাগ; আই)
ইয়ার্ডান জর্জিভ

5

আমরা কি ভুল দিক থেকে আসছি না?

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

যদি আপনি জানেন যে মোতায়েন করা রিলিজের জন্য সম্ভাব্য মানগুলির সেটটি স্থির করা হয়, তবে একটি এনাম পছন্দনীয়।

আপনি যদি আপনার ডাটাবেসে অবশ্যই কিছু আছে যা গণিতের সেটটিকে প্রতিলিপি করে তোলে, তবে এনাম মানগুলির নির্দিষ্ট সংকলন সহ ডাটাবেস টেবিলটি পরিষ্কার এবং পুনরায় তৈরি করার জন্য কেন একটি পদক্ষেপ যুক্ত করবেন না?


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

4

আমি সবসময় আমার নিজের "কাস্টম এনাম" লিখতে পছন্দ করি। আমার এক ক্লাসের চেয়ে কিছুটা জটিল, তবে আমি এটি আবার ব্যবহার করতে পারি:

public abstract class CustomEnum
{
    private readonly string _name;
    private readonly object _id;

    protected CustomEnum( string name, object id )
    {
        _name = name;
        _id = id;
    }

    public string Name
    {
        get { return _name; }
    }

    public object Id
    {
        get { return _id; }
    }

    public override string ToString()
    {
        return _name;
    }
}

public abstract class CustomEnum<TEnumType, TIdType> : CustomEnum
    where TEnumType : CustomEnum<TEnumType, TIdType>
{
    protected CustomEnum( string name, TIdType id )
        : base( name, id )
    { }

    public new TIdType Id
    {
        get { return (TIdType)base.Id; }
    }

    public static TEnumType FromName( string name )
    {
        try
        {
            return FromDelegate( entry => entry.Name.Equals( name ) );
        }
        catch (ArgumentException ae)
        {
            throw new ArgumentException( "Illegal name for custom enum '" + typeof( TEnumType ).Name + "'", ae );
        }
    }

    public static TEnumType FromId( TIdType id )
    {
        try
        {
            return FromDelegate( entry => entry.Id.Equals( id ) );
        }
        catch (ArgumentException ae)
        {
            throw new ArgumentException( "Illegal id for custom enum '" + typeof( TEnumType ).Name + "'", ae );
        }
    }

    public static IEnumerable<TEnumType> GetAll()
    {
        var elements = new Collection<TEnumType>();
        var infoArray = typeof( TEnumType ).GetFields( BindingFlags.Public | BindingFlags.Static );

        foreach (var info in infoArray)
        {
            var type = info.GetValue( null ) as TEnumType;
            elements.Add( type );
        }

        return elements;
    }

    protected static TEnumType FromDelegate( Predicate<TEnumType> predicate )
    {
        if(predicate == null)
            throw new ArgumentNullException( "predicate" );

        foreach (var entry in GetAll())
        {
            if (predicate( entry ))
                return entry;
        }

        throw new ArgumentException( "Element not found while using predicate" );
    }
}

আমি এখন আমার এনামটি তৈরি করতে চাই যা আমি ব্যবহার করতে চাই:

 public sealed class SampleEnum : CustomEnum<SampleEnum, int>
    {
        public static readonly SampleEnum Element1 = new SampleEnum( "Element1", 1, "foo" );
        public static readonly SampleEnum Element2 = new SampleEnum( "Element2", 2, "bar" );

        private SampleEnum( string name, int id, string additionalText )
            : base( name, id )
        {
            AdditionalText = additionalText;
        }

        public string AdditionalText { get; private set; }
    }

শেষ পর্যন্ত আমি এটির মতো ব্যবহার করতে পারি:

 static void Main( string[] args )
        {
            foreach (var element in SampleEnum.GetAll())
            {
                Console.WriteLine( "{0}: {1}", element, element.AdditionalText );
                Console.WriteLine( "Is 'Element2': {0}", element == SampleEnum.Element2 );
                Console.WriteLine();
            }

            Console.ReadKey();
        }

এবং আমার আউটপুট হবে:

Element1: foo
Is 'Element2': False

Element2: bar
Is 'Element2': True    

2

আপনি System.Web.Compilation.BuildProvider চান

আমি এটি করার বুদ্ধি নিয়ে সন্দেহও করি তবে তারপরে এমন একটি ভাল ব্যবহারের কেস হতে পারে যা আমি ভাবতে পারি না।

আপনি যা সন্ধান করছেন তা হ'ল বিল্ড প্রোভাইডারগণ অর্থাৎ সিস্টেম. ওয়েবে.কম্পিলেশন B বিল্ডপ্রোভাইডার

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

আশাকরি এটা সাহায্য করবে.



0

আপনি যা চান তা করার কোনও ভাল উপায় আছে বলে আমি মনে করি না। এবং আপনি যদি এটি সম্পর্কে চিন্তা করেন তবে আমি মনে করি না এটি আপনি যা চান তা এটি।

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

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


0

ডায়নামিক এনাম ব্যবহার কোনওভাবেই খারাপ। ভবিষ্যতে সুস্পষ্ট এবং সহজ কোড বজায় রাখা সহজ কোডটি নিশ্চিত করতে আপনাকে ডেটাটিকে "অনুলিপি" দেওয়ার সমস্যায় পড়তে হবে।

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

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


0

এনামগুলিকে রাখার এবং একই সাথে মানগুলির একটি গতিশীল তালিকা তৈরির একটি উপায় হ'ল আপনার বর্তমানে ডায়নামিকালি তৈরি করা অভিধানের সাথে থাকা এনামগুলি ব্যবহার করা।

যেহেতু বেশিরভাগ এনামগুলি ব্যবহারের জন্য সংজ্ঞায়িত করা প্রসঙ্গে ব্যবহৃত হয় এবং "ডায়নামিক এনামগুলি" ডায়নামিক প্রক্রিয়া দ্বারা সমর্থিত হয়, আপনি 2 টি পার্থক্য করতে পারেন।

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

এখন আপনার গতিশীল এনামসের অংশটি এসেছে, আমি ধরে নিচ্ছি যে আপনি এনামগুলি এমন একটি শর্ত তৈরি করতে ব্যবহার করবেন যা নিয়মের একটি সেট প্রয়োগ করে, কিছু গতিশীলভাবে উত্পন্ন হয়।

Get integer from database
If Integer is in Enum -> create Enum -> then run Enum parts
If Integer is not a Enum -> create Dictionary from Table -> then run Dictionary parts.

0

বিল্ডার ক্লাস enum

public class XEnum
{
    private EnumBuilder enumBuilder;
    private int index;
    private AssemblyBuilder _ab;
    private AssemblyName _name;
    public XEnum(string enumname)
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        _name = new AssemblyName("MyAssembly");
        _ab = currentDomain.DefineDynamicAssembly(
            _name, AssemblyBuilderAccess.RunAndSave);

        ModuleBuilder mb = _ab.DefineDynamicModule("MyModule");

        enumBuilder = mb.DefineEnum(enumname, TypeAttributes.Public, typeof(int));


    }
    /// <summary>
    /// adding one string to enum
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public FieldBuilder add(string s)
    {
        FieldBuilder f = enumBuilder.DefineLiteral(s, index);
        index++;
        return f;
    }
    /// <summary>
    /// adding array to enum
    /// </summary>
    /// <param name="s"></param>
    public void addRange(string[] s)
    {
        for (int i = 0; i < s.Length; i++)
        {
            enumBuilder.DefineLiteral(s[i], i);
        }
    }
    /// <summary>
    /// getting index 0
    /// </summary>
    /// <returns></returns>
    public object getEnum()
    {
        Type finished = enumBuilder.CreateType();
        _ab.Save(_name.Name + ".dll");
        Object o1 = Enum.Parse(finished, "0");
        return o1;
    }
    /// <summary>
    /// getting with index
    /// </summary>
    /// <param name="i"></param>
    /// <returns></returns>
    public object getEnum(int i)
    {
        Type finished = enumBuilder.CreateType();
        _ab.Save(_name.Name + ".dll");
        Object o1 = Enum.Parse(finished, i.ToString());
        return o1;
    }
}

একটি বস্তু তৈরি করুন

string[] types = { "String", "Boolean", "Int32", "Enum", "Point", "Thickness", "long", "float" };
XEnum xe = new XEnum("Enum");
        xe.addRange(types);
        return xe.getEnum();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.