Tự động tạo Enum dựa trên các giá trị trong bảng tra cứu cơ sở dữ liệu?


116

Làm cách nào để tôi tự động tạo một enum và sau đó sử dụng các giá trị của nó trong C # dựa trên các giá trị trong bảng tra cứu cơ sở dữ liệu (sử dụng lớp dữ liệu thư viện doanh nghiệp)?

Ví dụ: Nếu tôi thêm một giá trị tra cứu mới trong cơ sở dữ liệu, tôi không muốn phải thêm khai báo giá trị enum tĩnh bổ sung trong mã theo cách thủ công - Tôi muốn giữ cho enum đồng bộ với cơ sở dữ liệu.

Có một điều như thế này?


Tôi không muốn tạo một mã enum tĩnh được tạo (theo bài viết Dự án mã Enum Code Generator - Tạo mã enum tự động từ bảng tra cứu cơ sở dữ liệu ) và muốn nó hoàn toàn tự động.


Có thể là bạn đang cố gắng sử dụng kiểu liệt kê theo cách mà có một giải pháp tốt hơn không?
Dan

Tôi với @Dan, phải có một cách tốt hơn để làm điều này.
N_A

@mydogisbox cách tốt hơn là gì?
eran otzap

@eranotzer Trên thực tế, sau khi suy nghĩ về nó một chút, sẽ khá đơn giản để viết một bước xây dựng trước truy vấn DB và tạo một enum từ nó
N_A

1
Điều đó đang được nói, tôi không chắc ý của anh ấy khi nói "Tôi không muốn tạo một mã được tạo tĩnh enum", vì vậy có thể điều này không phù hợp với nhu cầu.
N_A

Câu trả lời:


97

Tôi đang làm điều này chính xác, nhưng bạn cần phải thực hiện một số loại tạo mã để điều này hoạt động.

Trong giải pháp của mình, tôi đã thêm một dự án "EnumeratedTypes". Đây là một ứng dụng console lấy tất cả các giá trị từ cơ sở dữ liệu và xây dựng các enums từ chúng. Sau đó, nó lưu tất cả các enum vào một assembly.

Mã tạo enum như sau:

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

Các dự án khác của tôi trong giải pháp tham khảo lắp ráp được tạo này. Kết quả là, sau đó tôi có thể sử dụng các enums động trong mã, hoàn chỉnh với intellisense.

Sau đó, tôi đã thêm một sự kiện hậu xây dựng để sau khi dự án "EnumeratedTypes" này được tạo, nó tự chạy và tạo tệp "MyEnums.dll".

Nhân tiện, nó sẽ giúp thay đổi thứ tự xây dựng của dự án của bạn để "EnumeratedTypes" được tạo trước. Nếu không, khi bạn bắt đầu sử dụng .dll được tạo động của mình, bạn sẽ không thể tạo bản dựng nếu .dll bị xóa. (Con gà và quả trứng là vấn đề - các dự án khác của bạn trong giải pháp cần .dll này để xây dựng đúng cách và bạn không thể tạo .dll cho đến khi bạn xây dựng giải pháp của mình ...)

Tôi nhận được hầu hết các mã ở trên từ bài viết msdn này .

Hi vọng điêu nay co ich!


7
Đối với những người không biết cách chạy tệp thực thi kết quả sau khi xây dựng: 1) Nhấp chuột phải vào dự án 2) Nhấp vào thuộc tính 3) Nhấp vào Tạo sự kiện 4) Trên hộp văn bản "Dòng lệnh sự kiện sau xây dựng" $ (TargetPath)
Miguel

Có thể thực hiện Dynamic Enum với định nghĩa thuộc tính tùy chỉnh như đã đề cập trong liên kết này không?
Balagurunathan Marimuthu

49

Enums phải được chỉ định tại thời điểm biên dịch, bạn không thể thêm động enums trong thời gian chạy - và tại sao bạn lại không sử dụng / tham chiếu đến chúng trong mã?

Từ Professional C # 2008:

Sức mạnh thực sự của enums trong C # là đằng sau hậu trường, chúng được khởi tạo dưới dạng cấu trúc bắt nguồn từ lớp cơ sở, System.Enum. Điều này có nghĩa là có thể gọi các phương thức chống lại chúng để thực hiện một số tác vụ hữu ích. Lưu ý rằng do cách .NET Framework được triển khai nên không có sự mất hiệu suất nào liên quan đến việc coi enums theo cú pháp là cấu trúc. Trong thực tế, một khi mã của bạn được biên dịch, enum sẽ tồn tại dưới dạng các kiểu nguyên thủy, giống như int và float.

Vì vậy, tôi không chắc bạn có thể sử dụng Enums theo cách bạn muốn.


1
không chắc lý do của billfredtom là gì, nhưng của tôi là tôi có thể tránh thực hiện tra cứu chuỗi thủ công cho một số khóa nhất định, thay vào đó, chúng được tích hợp vào mã của tôi. Tôi chỉ thích có thể thực hiện logic trên các giá trị được nhập mạnh thay vì các chuỗi yếu. Một lưu ý là, vì bây giờ chúng ta có mã dựa trên Enum được tạo động, nếu chúng ta xóa giá trị khỏi cơ sở dữ liệu, thì lần sau khi chúng ta cố gắng biên dịch mã của mình, nó sẽ không thành công.
Pandincus

14
Áp phích và 18 lượt ủng hộ đã bỏ sót quan điểm của anh ấy. Có vẻ như anh ấy muốn enum được tạo , không phải enum động thời gian chạy.
Matt Mitchell,

+1. Về cơ bản, enum chỉ là một cách khác để xác định các hằng số nguyên (ngay cả khi System.Enumcó một số chức năng bổ sung). Thay vì viết const int Red=0, Green=1, Blue=3;Bạn viết enum { Red, Green, Blue }. Theo định nghĩa, một hằng số là hằng số và không động.
Olivier Jacot-Descombes

2
@Oliver Nếu bạn muốn tranh luận về ngữ nghĩa, vâng, bạn đúng. Nhưng tôi đồng ý với nhận xét của Graphain - tôi tin rằng OP đang tìm kiếm các enum được tạo ra . Anh ta muốn các giá trị enum đến từ cơ sở dữ liệu và không phải mã hóa chúng.
Pandincus

1
Hoặc ... giả sử tôi cho phép ai đó trong web.config của mình xác định các loại mã thông báo cho các mẫu email cho mã tạo mẫu email của tôi. Sẽ thật tuyệt nếu enum hiện tại của tôi có tên là EmailTokens đại diện cho các loại chuỗi đó sẽ được định vị dựa trên các loại được định nghĩa trong web.config của tôi. Vì vậy, nếu có ai đó thêm mã thông báo email mới vào webconfig thông qua giá trị khóa của tôi, ví dụ: "Email, FName" và tôi đã có một enum mà tôi sẽ sử dụng để đại diện cho các mã thông báo này chẳng hạn như EmailTemplate. Email sẽ rất tuyệt nếu ai đó có thể chỉ thêm mã thông báo chuỗi mới trong khóa đó trong web.config và enum của tôi sẽ tự động thêm const
PositiveGuy

18

Nó có phải là một enum thực tế không? Làm thế nào về việc sử dụng một Dictionary<string,int>thay thế?

ví dụ

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

11
Tôi sẽ không cố gắng làm theo cách này. Bạn mất kiểm tra thời gian biên dịch và dễ bị lỗi đánh máy. Tất cả các lợi ích của enums đã biến mất. Bạn có thể giới thiệu hằng số chuỗi, nhưng sau đó bạn quay lại nơi bạn bắt đầu.
Daniel Brückner

1
Tôi đồng ý. Nhưng hãy nhớ rằng các chuỗi bị nhập sai sẽ bị bắt trong thời gian chạy. Chỉ cần thêm một trường hợp thử nghiệm để bao gồm tất cả các thành viên enum.
Autodidact

1
nhập sai không phải là một vấn đề nếu bạn sử dụng hằng số thay vì literals
Maslow

@Maslow Giả sử bạn có nghĩa là enums, không phải hằng số chuỗi.
Matt Mitchell,

4
+1. Sử dụng từ điển hoặc HashSet gần nhất với những gì có thể là một enum động. Hoàn toàn động có nghĩa là nó xảy ra trong thời gian chạy và do đó việc kiểm tra lỗi sẽ phải xảy ra trong thời gian chạy.
Olivier Jacot-Descombes

13

Tôi đã làm điều này với mẫu T4 . Khá đơn giản khi thả tệp .tt vào dự án của bạn và thiết lập Visual Studio để chạy mẫu T4 như một bước xây dựng trước.

T4 tạo một tệp .cs, có nghĩa là bạn có thể yêu cầu nó chỉ cần truy vấn cơ sở dữ liệu và tạo một enum trong tệp .cs từ kết quả. Được kết nối như một nhiệm vụ trước khi xây dựng, nó sẽ tạo lại enum của bạn trên mọi bản dựng hoặc thay vào đó bạn có thể chạy T4 theo cách thủ công nếu cần.


12

Giả sử bạn có những thứ sau trong DB của mình:

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

Tạo một vùng chọn để nhận các giá trị bạn cần:

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

Xây dựng mã nguồn cho enum và bạn sẽ nhận được những thứ như sau:

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

(rõ ràng là điều này được xây dựng trong một số loại vòng lặp.)

Sau đó đến phần thú vị, Biên dịch enum của bạn và sử dụng nó:

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

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

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

Bây giờ bạn có kiểu được biên dịch và sẵn sàng để sử dụng.
Để nhận một giá trị enum được lưu trữ trong DB, bạn có thể sử dụng:

[Enum].Parse(enumType, value);

trong đó giá trị có thể là giá trị số nguyên (0, 1, v.v.) hoặc văn bản / khóa enum (Apple, Banana, v.v.)


4
Điều này thực sự sẽ giúp ích gì? Không có kiểu an toàn và không có nội dung. Về cơ bản, đó chỉ là một cách phức tạp hơn để sử dụng hằng số vì dù sao thì anh ta cũng phải cung cấp giá trị.
Runeborg

2
Sani - hoàn hảo! Đây chính xác là những gì tôi cần. Đối với những người đặt câu hỏi về lý do của một cái gì đó như thế này, tôi đang sử dụng một thư viện của nhà cung cấp yêu cầu một thuộc tính được đặt thành tên của một kiểu liệt kê. Phép liệt kê giới hạn phạm vi giá trị hợp lệ cho một thuộc tính khác của cùng một đối tượng. Trong trường hợp của tôi, tôi đang tải siêu dữ liệu, bao gồm phạm vi giá trị hợp lệ từ cơ sở dữ liệu; và không, mã nhà cung cấp không hỗ trợ chuyển tập hợp thuộc bất kỳ loại nào đến thuộc tính. Cảm ơn

10

Chỉ hiển thị câu trả lời của Pandincus với mã "của kệ" và một số giải thích: Bạn cần hai giải pháp cho ví dụ này (tôi biết nó cũng có thể được thực hiện thông qua một;), hãy để các sinh viên nâng cao trình bày nó ...

Vì vậy, đây là DDL SQL cho bảng:

USE [ocms_dev]
    GO

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

Vì vậy, đây là chương trình console tạo ra 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 

Đây là lập trình Console in đầu ra (hãy nhớ rằng nó phải tham chiếu đến dll). Hãy để các sinh viên trước trình bày giải pháp kết hợp mọi thứ trong một giải pháp với tải động và kiểm tra xem đã có dll xây dựng chưa.

// 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
@YordanGeorgiev -Tại sao bạn lại khai báo flagFileExistskhi nó không được sử dụng ở bất kỳ nơi nào khác trong ứng dụng?
Michael Kniskern

2
Tôi đoán nó là một lỗi hơn; I)
Yordan Georgiev

5

Không phải chúng ta đến từ sai hướng sao?

Nếu dữ liệu có khả năng thay đổi trong suốt thời gian tồn tại của bản phát hành đã triển khai thì enum không phù hợp và bạn cần sử dụng từ điển, băm hoặc bộ sưu tập động khác.

Nếu bạn biết tập hợp các giá trị có thể được cố định cho vòng đời của bản phát hành đã triển khai, thì một enum sẽ thích hợp hơn.

Nếu bạn phải có thứ gì đó trong cơ sở dữ liệu của mình sao chép tập hợp được liệt kê, thì tại sao không thêm bước triển khai để xóa và tái tạo bảng cơ sở dữ liệu với tập giá trị enum cuối cùng?


Có và không, Có bởi vì bạn nói đúng, toàn bộ điểm là enum là tĩnh. Bạn có thể tránh các lỗi đánh máy và cũng biết những gì có sẵn. Với từ điển và db - có thể là bất cứ thứ gì. Nhưng đôi khi bạn muốn có quả của cả hai cây khi bạn chỉ được phép hái từ một cây.
Ken

4

Tôi luôn thích viết "custom enum" của riêng mình. Hơn tôi có một lớp phức tạp hơn một chút, nhưng tôi có thể sử dụng lại nó:

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

Bây giờ tôi chỉ cần tạo enum của mình mà tôi muốn sử dụng:

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

Cuối cùng tôi có thể sử dụng nó như tôi muốn:

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

Và đầu ra của tôi sẽ là:

Element1: foo
Is 'Element2': False

Element2: bar
Is 'Element2': True    

2

Bạn muốn System.Web.Compilation.BuildProvider

Tôi cũng nghi ngờ sự khôn ngoan của việc làm này, nhưng sau đó có thể có một trường hợp sử dụng tốt mà tôi không thể nghĩ ra.

Những gì bạn đang tìm kiếm là Nhà cung cấp bản dựng, tức là System.Web.Compilation.BuildProvider

Họ đang sử dụng rất hiệu quả bởi cận âm , bạn có thể tải về mã nguồn và xem cách họ sử dụng chúng, bạn sẽ không cần bất cứ điều gì nửa như phức tạp như những gì họ đang làm.

Hi vọng điêu nay co ich.



0

Tôi không nghĩ rằng có một cách tốt để làm những gì bạn muốn. Và nếu bạn nghĩ về nó, tôi không nghĩ đây là điều bạn thực sự muốn.

Nếu bạn có một enum động, điều đó cũng có nghĩa là bạn phải cung cấp cho nó một giá trị động khi bạn tham chiếu nó. Có thể với rất nhiều phép thuật, bạn có thể đạt được một số loại IntelliSense sẽ xử lý việc này và tạo một enum cho bạn trong một tệp DLL. Nhưng hãy xem xét khối lượng công việc sẽ mất, việc truy cập cơ sở dữ liệu để lấy thông tin IntelliSense sẽ không hiệu quả như thế nào cũng như cơn ác mộng của phiên bản kiểm soát tệp DLL được tạo.

Nếu bạn thực sự không muốn thêm các giá trị enum theo cách thủ công (bạn sẽ phải thêm chúng vào cơ sở dữ liệu) thay vào đó, hãy sử dụng công cụ tạo mã, ví dụ như mẫu T4 . Nhấp chuột phải + chạy và bạn có enum được định nghĩa tĩnh trong mã và bạn nhận được tất cả các lợi ích của việc sử dụng enum.


0

Sử dụng enum động là không tốt cho dù theo cách nào. Bạn sẽ phải trải qua rắc rối khi "nhân bản" dữ liệu để đảm bảo mã rõ ràng và dễ bảo trì trong tương lai.

Nếu bạn bắt đầu giới thiệu các thư viện được tạo tự động, bạn chắc chắn sẽ gây ra nhiều nhầm lẫn hơn cho các nhà phát triển trong tương lai khi phải nâng cấp mã của bạn hơn là chỉ làm cho enum của bạn được mã hóa trong đối tượng lớp thích hợp.

Các ví dụ khác được đưa ra nghe có vẻ hay và thú vị, nhưng hãy nghĩ về chi phí duy trì mã so với những gì bạn nhận được từ nó. Ngoài ra, những giá trị đó có thường xuyên thay đổi không?


0

Một cách để giữ Enums và tạo danh sách giá trị Động cùng lúc là sử dụng Enums mà bạn hiện có với Từ điển được tạo động.

Vì hầu hết các Enum được sử dụng trong ngữ cảnh mà chúng được xác định để sử dụng và "các Enum động" sẽ được hỗ trợ bởi các quy trình động, bạn có thể phân biệt cả hai.

Bước đầu tiên là tạo một bảng / bộ sưu tập chứa ID và Tham chiếu cho Mục nhập Động. Trong bảng, bạn sẽ tự động tăng giá trị lớn hơn nhiều so với giá trị Enum lớn nhất của bạn.

Bây giờ đến phần dành cho Enums động của bạn, tôi giả sử rằng bạn sẽ sử dụng Enums để tạo một tập hợp các điều kiện áp dụng một tập hợp các quy tắc, một số được tạo động.

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

lớp xây dựng 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;
    }
}

tạo một đối tượng

string[] types = { "String", "Boolean", "Int32", "Enum", "Point", "Thickness", "long", "float" };
XEnum xe = new XEnum("Enum");
        xe.addRange(types);
        return xe.getEnum();
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.