Secara otomatis membuat Enum berdasarkan nilai dalam tabel pencarian database?

116

Bagaimana cara membuat enum secara otomatis dan kemudian menggunakan nilainya di C # berdasarkan nilai dalam tabel pencarian database (menggunakan lapisan data perpustakaan perusahaan)?

Misalnya, Jika saya menambahkan nilai pencarian baru di database, saya tidak ingin menambahkan deklarasi nilai enum statis ekstra secara manual dalam kode - saya ingin agar enum tetap sinkron dengan database.

Apakah ada yang seperti ini?


Saya tidak ingin membuat kode yang dihasilkan enum statis (sesuai artikel Proyek Kode Enum Code Generator - Menghasilkan kode enum secara otomatis dari tabel pencarian database ) dan lebih suka itu sepenuhnya otomatis.

billfredtom.dll
sumber
Mungkinkah Anda mencoba menggunakan enumerasi dengan cara di mana ada solusi yang lebih baik?
Dan
Saya bersama @Dan, pasti ada cara yang lebih baik untuk melakukan ini.
N_A
@mydogisbox apa cara yang lebih baik?
eran otzap
@eranotzer Sebenarnya, setelah memikirkannya sebentar, akan sangat mudah untuk menulis langkah pra-bangun yang menanyakan DB dan menghasilkan enum darinya
N_A
1
Karena itu, saya tidak yakin apa yang dia maksud dengan "Saya tidak ingin membuat kode yang dihasilkan enum statis", jadi mungkin ini tidak sesuai dengan kebutuhan.
N_A

Jawaban:

97

Saya melakukan hal yang persis seperti ini, tetapi Anda perlu melakukan semacam pembuatan kode agar ini berfungsi.

Dalam solusi saya, saya menambahkan proyek "EnumeratedTypes". Ini adalah aplikasi konsol yang mendapatkan semua nilai dari database dan membuat enum darinya. Kemudian itu menyimpan semua enum ke sebuah assembly.

Kode pembuatan enum seperti ini:

// 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");

Proyek saya yang lain dalam referensi solusi perakitan yang dihasilkan ini. Hasilnya, saya kemudian dapat menggunakan enum dinamis dalam kode, lengkap dengan intellisense.

Kemudian, saya menambahkan acara pasca-pembangunan sehingga setelah proyek "EnumeratedTypes" ini dibuat, ia berjalan sendiri dan menghasilkan file "MyEnums.dll".

Ngomong-ngomong, ada baiknya mengubah urutan build project Anda sehingga "EnumeratedTypes" dibuat terlebih dahulu. Jika tidak, setelah Anda mulai menggunakan .dll yang dihasilkan secara dinamis, Anda tidak akan dapat melakukan build jika .dll pernah terhapus. (Masalah ayam dan telur - proyek Anda yang lain dalam solusi membutuhkan .dll ini untuk dibangun dengan benar, dan Anda tidak dapat membuat .dll sampai Anda membangun solusi Anda ...)

Saya mendapatkan sebagian besar kode di atas dari artikel msdn ini .

Semoga ini membantu!

Pandincus
sumber
7
Bagi mereka yang tidak tahu cara menjalankan hasil eksekusi pada post-build: 1) Klik kanan proyek 2) Klik pada properti 3) Klik pada Build Events 4) Pada jenis kotak teks "Post-build event command lines" $ (TargetPath)
Miguel
Apakah mungkin untuk melakukan Dynamic Enum dengan definisi atribut khusus seperti yang disebutkan dalam tautan ini ?
Balagurunathan Marimuthu
49

Enum harus ditentukan pada waktu kompilasi, Anda tidak dapat menambahkan enum secara dinamis selama run-time - dan mengapa Anda, tidak akan ada gunanya / referensi ke dalamnya dalam kode?

Dari Professional C # 2008:

Kekuatan sebenarnya dari enum di C # adalah bahwa di balik layar mereka dibuat sebagai struct yang berasal dari kelas dasar, System.Enum. Artinya adalah mungkin untuk memanggil metode terhadap mereka untuk melakukan beberapa tugas yang berguna. Perhatikan bahwa karena cara .NET Framework diimplementasikan, tidak ada kehilangan kinerja yang terkait dengan memperlakukan enum secara sintaksis sebagai struct. Dalam praktiknya, setelah kode Anda dikompilasi, enum akan ada sebagai tipe primitif, seperti int dan float.

Jadi, saya tidak yakin Anda dapat menggunakan Enum seperti yang Anda inginkan.

Marcus L.
sumber
1
tidak yakin apa alasan billfredtom itu, tetapi milik saya adalah bahwa saya dapat menghindari melakukan pencarian string manual untuk kunci tertentu, alih-alih membuatnya dibangun ke dalam kode saya. Saya hanya lebih suka dapat melakukan logika pada nilai yang diketik dengan kuat daripada string yang lemah. Peringatannya adalah, karena kita sekarang memiliki kode yang bergantung pada Enum yang dihasilkan secara dinamis, jika kita menghapus nilai dari database, saat berikutnya kita mencoba mengompilasi kode kita, itu akan gagal.
Pandincus
14
Poster dan 18 suara positif agak meleset dari maksudnya. Sepertinya dia menginginkan enum yang dihasilkan , bukan enum dinamis runtime.
Matt Mitchell
+1. Enum pada dasarnya hanyalah cara lain untuk mendefinisikan konstanta integer (meskipun System.Enummemiliki beberapa fungsi tambahan). Alih-alih menulis, const int Red=0, Green=1, Blue=3;Anda menulis enum { Red, Green, Blue }. Konstanta menurut definisi adalah konstan dan tidak dinamis.
Olivier Jacot-Descombes
2
@Oliver Jika Anda ingin memperdebatkan semantik, ya, Anda benar. Tapi saya setuju dengan komentar Graphain - Saya yakin OP sedang mencari enum yang dihasilkan . Dia ingin nilai enum berasal dari database dan tidak harus melakukan hard-code untuk itu.
Pandincus
1
Atau ... katakanlah saya mengizinkan seseorang di web.config saya menentukan jenis token untuk templat email untuk kode templat email saya. Alangkah baiknya jika enum saya yang ada bernama EmailTokens yang mewakili jenis string tersebut akan digenkan berdasarkan jenis yang ditentukan di web.config saya. Jadi, jika ada yang menambahkan token email baru di webconfig melalui nilai kunci saya misalnya "Email, FName" dan saya sudah memiliki enum yang akan saya gunakan untuk mewakili token ini seperti EmailTemplate. Email alangkah baiknya jika ada yang bisa tambahkan token string baru di kunci itu di web.config dan enum saya akan secara otomatis menambahkan const
PositiveGuy
18

Apakah itu harus enum yang sebenarnya? Bagaimana kalau menggunakan a Dictionary<string,int>sebagai gantinya?

sebagai contoh

Dictionary<string, int> MyEnum = new Dictionary(){{"One", 1}, {"Two", 2}};
Console.WriteLine(MyEnum["One"]);
Otodidak
sumber
11
Saya tidak akan mencoba melakukannya dengan cara ini. Anda kehilangan pemeriksaan waktu kompilasi dan menjadi rentan terhadap kesalahan pengetikan. Semua manfaat enum hilang. Anda bisa memperkenalkan konstanta string, tapi kemudian Anda kembali ke awal.
Daniel Brückner
1
Saya setuju. Tapi ingat string yang salah ketik akan tertangkap saat runtime. Cukup tambahkan kasus uji untuk mencakup semua anggota enum.
Autodidak
1
kesalahan ketik tidak menjadi masalah jika Anda menggunakan konstanta, bukan literal
Maslow
@Maslow Asumsikan yang Anda maksud enum, bukan konstanta string.
Matt Mitchell
4
+1. Menggunakan kamus atau HashSet paling mendekati apa yang bisa menjadi enum dinamis. Dinamis penuh berarti bahwa hal itu terjadi pada waktu proses dan oleh karena itu pemeriksaan kesalahan harus terjadi pada waktu proses.
Olivier Jacot-Descombes
13

Saya telah melakukan ini dengan template T4 . Sangat mudah untuk menjatuhkan file .tt ke dalam proyek Anda, dan mengatur Visual Studio untuk menjalankan template T4 sebagai langkah pra-bangun.

T4 menghasilkan file .cs, yang berarti Anda dapat meminta database dan membuat enum dalam file .cs dari hasilnya. Dipasang sebagai tugas pra-build, itu akan membuat ulang enum Anda pada setiap build, atau Anda dapat menjalankan T4 secara manual sesuai kebutuhan.

CodingWithSpike
sumber
12

Katakanlah Anda memiliki yang berikut ini di DB Anda:

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 |
----------------------------------

Buat seleksi untuk mendapatkan nilai yang Anda butuhkan:

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

Buat kode sumber untuk enum dan Anda akan mendapatkan sesuatu seperti:

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

(jelas ini dibangun dalam semacam loop.)

Kemudian tibalah bagian yang menyenangkan, Mengompilasi enum Anda dan menggunakannya:

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

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

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

Sekarang Anda memiliki tipe yang telah dikompilasi dan siap digunakan.
Untuk mendapatkan nilai enum yang disimpan di DB, Anda dapat menggunakan:

[Enum].Parse(enumType, value);

di mana nilai dapat berupa nilai integer (0, 1, dll.) atau teks / kunci enum (Apple, Banana, dll.)

Sani Singh Huttunen
sumber
4
Dalam hal apa ini benar-benar membantu? Tidak ada keamanan tipe dan tidak ada kecerdasan. Pada dasarnya ini hanya cara yang lebih rumit dalam menggunakan konstanta karena dia harus memberikan nilainya.
Runeborg
2
Sani - sempurna! Inilah yang saya butuhkan. Bagi mereka yang mempertanyakan alasan untuk hal seperti ini, saya menggunakan pustaka vendor yang memerlukan properti untuk disetel ke nama enumerasi. Pencacahan membatasi kisaran nilai yang valid untuk properti berbeda dari objek yang sama. Dalam kasus saya, saya memuat metadata, termasuk kisaran nilai yang valid dari database; dan tidak, kode vendor tidak mendukung penerusan koleksi jenis apa pun ke properti. Terima kasih
10

Hanya menunjukkan jawaban Pandincus dengan kode "dari rak" dan beberapa penjelasan: Anda memerlukan dua solusi untuk contoh ini (saya tahu itu bisa dilakukan melalui satu juga;), biarkan siswa tingkat lanjut mempresentasikannya ...

Jadi inilah DDL SQL untuk tabel:

USE [ocms_dev]
    GO

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

Jadi, inilah program konsol yang memproduksi 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 

Berikut adalah program Konsol mencetak output (ingat bahwa itu harus mengacu pada dll). Biarkan siswa tingkat lanjut mempresentasikan solusi untuk menggabungkan semuanya dalam satu solusi dengan pembebanan dinamis dan memeriksa apakah sudah ada build dll.

// 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
Yordan Georgiev
sumber
1
@YordanGeorgiev -Mengapa Anda mendeklarasikannya flagFileExistsjika tidak digunakan di tempat lain dalam aplikasi?
Michael Kniskern
2
Saya kira itu adalah bug dari; I)
Yordan Georgiev
5

Bukankah kita sampai pada ini dari arah yang salah?

Jika data kemungkinan akan berubah sama sekali selama masa rilis yang diterapkan maka enum tidak sesuai, dan Anda perlu menggunakan kamus, hash, atau koleksi dinamis lainnya.

Jika Anda tahu bahwa kumpulan nilai yang mungkin telah diperbaiki selama masa pakai rilis yang diterapkan, maka enum lebih disukai.

Jika Anda harus memiliki sesuatu dalam database Anda yang mereplikasi set enumerasi, mengapa tidak menambahkan langkah penerapan untuk menghapus dan mengisi kembali tabel database dengan set definitif dari nilai enumerasi?

Brian Lowe
sumber
Ya dan tidak, Ya karena Anda benar, intinya adalah enum statis. Anda dapat menghindari kesalahan pengetikan dan juga mengetahui apa yang tersedia. Dengan kamus dan db - bisa apa saja. Tetapi terkadang Anda menginginkan buah dari kedua pohon ketika Anda hanya diperbolehkan memetik dari satu pohon.
Ken
4

Saya selalu suka menulis "enum kustom" saya sendiri. Daripada saya memiliki satu kelas yang sedikit lebih kompleks, tetapi saya dapat menggunakannya kembali:

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" );
    }
}

Sekarang saya hanya perlu membuat enum yang ingin saya gunakan:

 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; }
    }

Akhirnya saya bisa menggunakannya seperti yang saya inginkan:

 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();
        }

Dan keluaran saya adalah:

Element1: foo
Is 'Element2': False

Element2: bar
Is 'Element2': True    
Traummaennlein
sumber
2

Anda ingin System.Web.Compilation.BuildProvider

Saya juga meragukan kebijaksanaan melakukan ini, tetapi mungkin ada kasus penggunaan yang baik yang tidak dapat saya pikirkan.

Apa yang Anda cari adalah Build Providers yaitu System.Web.Compilation.BuildProvider

Mereka digunakan dengan sangat efektif oleh SubSonic , Anda dapat mengunduh sumbernya dan melihat bagaimana mereka menggunakannya, Anda tidak memerlukan apa pun yang setengah rumit seperti yang mereka lakukan.

Semoga ini membantu.

Biner Worrier
sumber
0

Menurut saya tidak ada cara yang baik untuk melakukan apa yang Anda inginkan. Dan jika Anda memikirkannya, saya rasa ini bukan yang Anda inginkan.

Jika Anda memiliki enum dinamis, itu juga berarti Anda harus memberinya makan dengan nilai dinamis saat Anda mereferensikannya. Mungkin dengan banyak keajaiban Anda bisa mencapai semacam IntelliSense yang akan menangani ini dan menghasilkan enum untuk Anda dalam file DLL. Tetapi pertimbangkan jumlah pekerjaan yang akan dilakukan, betapa tidak efektifnya mengakses database untuk mengambil informasi IntelliSense serta mimpi buruk versi yang mengontrol file DLL yang dihasilkan.

Jika Anda benar-benar tidak ingin menambahkan nilai enum secara manual (Anda tetap harus menambahkannya ke database), gunakan alat pembuat kode, misalnya template T4 . Klik kanan + jalankan dan enum Anda secara statis ditentukan dalam kode dan Anda mendapatkan semua keuntungan menggunakan enum.

Runeborg
sumber
0

Menggunakan enum dinamis itu buruk, bagaimanapun caranya. Anda harus melalui masalah "menduplikasi" data untuk memastikan kode yang jelas dan mudah dipelihara di masa mendatang.

Jika Anda mulai memperkenalkan pustaka yang dibuat secara otomatis, Anda pasti menyebabkan lebih banyak kebingungan bagi pengembang di masa mendatang karena harus meningkatkan kode Anda daripada sekadar membuat kode enum Anda dalam objek kelas yang sesuai.

Contoh lain yang diberikan terdengar bagus dan menarik, tetapi pikirkan tentang overhead pada pemeliharaan kode versus apa yang Anda dapatkan darinya. Juga, apakah nilai-nilai itu akan berubah sesering itu?

Martin
sumber
0

Salah satu cara untuk menyimpan Enum dan membuat daftar nilai Dinamis pada saat yang sama adalah dengan menggunakan Enum yang saat ini Anda miliki dengan Dictionary yang dibuat secara dinamis.

Karena sebagian besar Enum digunakan dalam konteks yang ditentukan untuk digunakan, dan "enum dinamis" akan didukung oleh proses dinamis, Anda dapat membedakan 2.

Langkah pertama adalah membuat tabel / koleksi yang menampung ID dan Referensi untuk Entri Dinamis. Dalam tabel, Anda akan menaikkan otomatis jauh lebih besar daripada nilai Enum terbesar Anda.

Sekarang sampai pada bagian untuk Enum dinamis Anda, saya berasumsi bahwa Anda akan menggunakan Enum untuk membuat satu set kondisi yang menerapkan seperangkat aturan, beberapa dibuat secara dinamis.

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.
Jackstine
sumber
0

kelas pembangun 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;
    }
}

buat sebuah objek

string[] types = { "String", "Boolean", "Int32", "Enum", "Point", "Thickness", "long", "float" };
XEnum xe = new XEnum("Enum");
        xe.addRange(types);
        return xe.getEnum();
Mahdi Khalili
sumber