데이터베이스 조회 테이블의 값을 기반으로 Enum을 자동으로 생성 하시겠습니까?


116

열거 형을 자동으로 생성 한 다음 데이터베이스 조회 테이블의 값을 기반으로 C #에서 해당 값을 사용하는 방법 (엔터프라이즈 라이브러리 데이터 레이어 사용)?

예를 들어, 데이터베이스에 새 조회 값을 추가하는 경우 코드에 추가 정적 열거 형 값 선언을 수동으로 추가 할 필요가 없습니다. 열거 형을 데이터베이스와 동기화 상태로 유지하고 싶습니다.

이것과 같은 것이 있습니까?


코드 생성 정적 열거 형 ( 코드 프로젝트 기사 Enum Code Generator-Generating enum code automatically from database look up tables에 따라 )을 생성하고 싶지 않으며 완전히 자동 인 것을 선호합니다.


더 나은 솔루션이있는 방식으로 열거 형을 사용하려고 할 수 있습니까?
Dan

저는 @Dan과 함께 있습니다. 더 나은 방법이 있어야합니다.
N_A

@mydogisbox 더 나은 방법은 무엇입니까?
eran otzap 2012

@eranotzer 사실 잠시 생각해 보면 DB를 쿼리하고 여기에서 열거 형을 생성하는 사전 빌드 단계를 작성하는 것은 매우 간단 할 것입니다.
N_A

1
즉, "정적 열거 형으로 생성 된 코드를 생성하고 싶지 않습니다."라는 말이 무슨 뜻인지 잘 모르겠습니다. 따라서 이것이 필요에 맞지 않을 수도 있습니다.
N_A 2011

답변:


97

나는이 정확한 일을하고 있어요,하지만 당신은 해야 할 일이에 대한 코드 생성의 어떤 종류의 일을 할 수 있습니다.

내 솔루션에서 "EnumeratedTypes"프로젝트를 추가했습니다. 이것은 데이터베이스에서 모든 값을 가져 와서 열거 형을 구성하는 콘솔 애플리케이션입니다. 그런 다음 모든 열거 형을 어셈블리에 저장합니다.

열거 형 생성 코드는 다음과 같습니다.

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

솔루션의 다른 프로젝트는이 생성 된 어셈블리를 참조합니다. 결과적으로 코드에서 인텔리 센스로 완성 된 동적 열거 형을 사용할 수 있습니다.

그런 다음이 "EnumeratedTypes"프로젝트가 빌드 된 후 자체적으로 실행되고 "MyEnums.dll"파일을 생성하도록 빌드 후 이벤트를 추가했습니다.

그건 그렇고, "EnumeratedTypes"가 먼저 빌드되도록 프로젝트 의 빌드 순서 를 변경하는 데 도움이됩니다 . 그렇지 않으면 동적으로 생성 된 .dll을 사용하기 시작하면 .dll이 삭제되면 빌드를 수행 할 수 없습니다. (닭고기와 달걀 종류의 문제-솔루션의 다른 프로젝트에서 제대로 빌드하려면이 .dll이 필요하며 솔루션을 빌드 할 때까지 .dll을 만들 수 없습니다 ...)

이 msdn 기사 에서 위의 코드 대부분을 얻었습니다 .

도움이 되었기를 바랍니다!


7
빌드 후 결과 실행 파일을 실행하는 방법을 모르는 경우 : 1) 프로젝트를 마우스 오른쪽 단추로 클릭하십시오. 2) 속성을 클릭하십시오. 3) 빌드 이벤트를 클릭하십시오. 4) "빌드 후 이벤트 명령 줄"텍스트 상자에 입력하십시오. $ (TargetPath)
Miguel

링크에 언급 된대로 사용자 정의 속성 정의를 사용하여 Dynamic Enum을 수행 할 수 있습니까?
Balagurunathan Marimuthu

49

열거 형은 컴파일 타임에 지정해야합니다. 런타임 동안에는 열거 형을 동적으로 추가 할 수 없습니다. 왜 코드에서 열거 형에 대한 사용 / 참조가 없을까요?

Professional C # 2008에서 :

C #에서 열거 형의 진정한 힘은 배후에서 기본 클래스 인 System.Enum에서 파생 된 구조체로 인스턴스화된다는 것입니다. 이것은 유용한 작업을 수행하기 위해 그들에 대해 메서드를 호출 할 수 있음을 의미합니다. .NET Framework가 구현되는 방식으로 인해 열거 형을 구문 적으로 구조체로 처리하는 것과 관련된 성능 손실은 없습니다. 실제로 코드가 컴파일되면 enum은 int 및 float처럼 기본 유형으로 존재합니다.

따라서 원하는 방식으로 Enum을 사용할 수 있는지 잘 모르겠습니다.


1
billfredtom의 추론이 무엇인지 확실하지 않지만 특정 키에 대한 수동 문자열 조회를 피할 수 있고 대신 내 코드에 내장 할 수 있다는 것입니다. 약한 문자열 대신 강력한 형식의 값에 대한 논리를 수행하는 것을 선호합니다. 주의 할 점은 동적으로 생성 된 Enum에 의존하는 코드가 있기 때문에 데이터베이스에서 값을 삭제하면 다음에 코드를 컴파일하려고 할 때 실패한다는 것입니다.
Pandincus 2010 년

14
포스터와 18 명의 찬성표가 그의 요점을 놓쳤습니다. 런타임 동적 열거 형이 아닌 생성 된 열거 형 을 원하는 것처럼 들립니다 .
Matt Mitchell

+1. 열거 형은 기본적으로 정수 상수를 정의하는 또 다른 방법입니다 ( System.Enum추가 기능이 있더라도 ). const int Red=0, Green=1, Blue=3;당신 이 쓰는 대신에 enum { Red, Green, Blue }. 상수는 정의상 상수이며 동적이 아닙니다.
Olivier Jacot-Descombes 2011

2
@Oliver 의미론을 주장하고 싶다면 맞습니다. 그러나 저는 Graphain의 의견에 동의합니다 .OP가 생성 된 열거 형을 찾고 있다고 생각합니다 . 그는 enum 값을 데이터베이스에서 가져오고 하드 코딩 할 필요가 없기를 원합니다.
Pandincus 2011

1
또는 내 web.config의 누군가가 내 이메일 템플릿 코드에 대한 이메일 템플릿의 토큰 유형을 정의하도록 허용한다고 가정합니다. 해당 문자열 유형을 나타내는 EmailTokens라는 기존 열거 형이 내 web.config에 정의 된 유형을 기반으로 생성되면 좋을 것입니다. 따라서 누군가가 내 키 값 (예 : "Email, FName")을 통해 webconfig에 새 이메일 토큰을 추가하고 EmailTemplate.Email과 같은 이러한 토큰을 나타내는 데 사용할 열거 형이 이미있는 경우 누구든지 가능하면 좋을 것입니다. web.config의 해당 키에 새 문자열 토큰을 추가하면 내 enum이 자동으로 const를 추가합니다.
PositiveGuy

18

실제 열거 형이어야합니까? Dictionary<string,int>대신 사용하는 것은 어떻습니까?

예를 들면

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

11
나는 그렇게하려고하지 않을 것입니다. 컴파일 시간 검사가 느슨해지고 입력 오류가 발생하기 쉽습니다. 열거 형의 모든 이점이 사라졌습니다. 문자열 상수를 도입 할 수 있지만 시작했던 곳으로 돌아 왔습니다.
Daniel Brückner

1
나는 동의한다. 그러나 잘못 입력 된 문자열은 런타임에 포착된다는 점을 기억하십시오. 모든 열거 형 멤버를 포함하는 테스트 케이스를 추가하기 만하면됩니다.
Autodidact

1
대신 리터럴 상수를 사용하는 경우 오타는 문제가되지 않습니다
매스로 우는

@Maslow 문자열 상수가 아니라 열거 형을 의미한다고 가정합니다.
Matt Mitchell

4
+1. 사전이나 HashSet을 사용하면 동적 열거 형에 가장 가깝습니다. 완전 동적이란 런타임에 발생하므로 런타임에 오류 검사가 발생해야 함을 의미합니다.
Olivier Jacot-Descombes 2011

13

T4 템플릿 으로이 작업을 수행했습니다 . .tt 파일을 프로젝트에 드롭하고 빌드 전 단계로 T4 템플릿을 실행하도록 Visual Studio를 설정하는 것은 매우 간단합니다.

T4는 .cs 파일을 생성하므로 데이터베이스를 쿼리하고 결과에서 .cs 파일에 열거 형을 만들 수 있습니다. 빌드 전 작업으로 연결되어 모든 빌드에서 열거 형을 다시 생성하거나 필요에 따라 T4를 수동으로 실행할 수 있습니다.


12

DB에 다음이 있다고 가정 해 보겠습니다.

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

이제 유형이 컴파일되고 사용할 준비가되었습니다.
DB에 저장된 enum 값을 얻으려면 다음을 사용할 수 있습니다.

[Enum].Parse(enumType, value);

여기서 value는 정수 값 (0, 1 등) 또는 열거 형 텍스트 / 키 (Apple, Banana 등) 일 수 있습니다.


4
이것이 실제로 어떤 방식으로 도움이 될까요? 유형 안전성과 지능이 없습니다. 어쨌든 그는 값을 제공해야하기 때문에 기본적으로 상수를 사용하는 더 복잡한 방법 일뿐입니다.
Runeborg

2
Sani-완벽합니다! 이것이 바로 내가 필요로하는 것이었다. 이와 같은 이유에 대해 의문을 제기하는 사람들을 위해 속성을 열거 형 이름으로 설정해야하는 공급 업체 라이브러리를 사용하고 있습니다. 열거는 동일한 객체의 다른 속성에 대한 유효한 값 범위를 제한합니다. 제 경우에는 데이터베이스에서 유효한 값 범위를 포함하여 메타 데이터를로드하고 있습니다. 아니요, 공급 업체 코드는 모든 유형의 컬렉션을 속성에 전달하는 것을 지원하지 않습니다. 감사합니다

10

Pandincus 의 을 "선반의"코드와 몇 가지 설명과 함께 보여 주기만하면됩니다.이 예제에는 두 가지 솔루션이 필요합니다 (하나를 통해 수행 할 수도 있음을 알고 있습니다;), 고급 학생들에게 발표하게하십시오.

따라서 다음은 테이블에 대한 DDL SQL입니다.

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을 참조해야 함). 고급 수강생이 모든 것을 하나의 솔루션에 동적 로딩과 결합하고 이미 빌드 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

1
@YordanGeorgiev- flagFileExists응용 프로그램의 다른 곳에서 사용되지 않는데 왜 선언 합니까?
Michael Kniskern

2
나는 그것이보다 버그라고 생각한다; I)
Yordan Georgiev

5

우리가 잘못된 방향에서 오는 것 아닌가요?

배포 된 릴리스의 수명 동안 데이터가 전혀 변경 될 가능성이있는 경우 열거 형은 적절하지 않으며 사전, 해시 또는 기타 동적 컬렉션을 사용해야합니다.

배포 된 릴리스의 수명 동안 가능한 값 집합이 고정되어 있음을 알고있는 경우 열거 형을 사용하는 것이 좋습니다.

당신이 경우 해야한다 열거 세트를 복제 데이터베이스에 뭔가를 가지고, 왜 지우고 열거 값의 최종 세트로 데이터베이스 테이블을 다시 채울 수있는 배포 단계를 추가하지?


예 및 아니오, 예가 정확하기 때문에 전체 요점은 정적입니다. 입력 오류를 방지하고 사용 가능한 내용도 알 수 있습니다. 사전과 db를 사용하면 무엇이든 될 수 있습니다. 그러나 때때로 당신은 당신이 오직 하나에서만 따를 수있을 때 두 나무의 열매를 원합니다.
Ken

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가 필요합니다.

나는 또한 이것을하는 것이 지혜로 운지 의심하지만, 내가 생각할 수없는 좋은 사용 사례가있을 수있다.

당신이 찾고있는 것은 빌드 공급자, 즉 System.Web.Compilation.BuildProvider입니다.

그들은 SubSonic 에서 매우 효과적으로 사용되며 , 소스를 다운로드하고 그들이 어떻게 사용하는지 볼 수 있으며, 그들이하는 일만큼 복잡한 것은 필요하지 않을 것입니다.

도움이 되었기를 바랍니다.



0

나는 당신이 원하는 것을하는 좋은 방법이 없다고 생각합니다. 그리고 당신이 그것에 대해 생각한다면 이것이 당신이 정말로 원하는 것이라고 생각하지 않습니다.

동적 열거 형이 있다면 참조 할 때 동적 값을 제공해야 함을 의미하기도합니다. 마법을 많이 사용하면 이를 처리하고 DLL 파일에 열거 형을 생성하는 일종의 IntelliSense 를 얻을 수 있습니다. 그러나 소요되는 작업량, IntelliSense 정보를 가져 오기 위해 데이터베이스에 액세스하는 것이 얼마나 비효율적 일지, 생성 된 DLL 파일을 제어하는 ​​버전의 악몽을 고려하십시오.

열거 형 값을 수동으로 추가하고 싶지 않은 경우 (어쨌든 데이터베이스에 추가해야 함) 대신 코드 생성 도구 (예 : T4 템플릿)를 사용하십시오. 마우스 오른쪽 버튼을 클릭하고 실행하면 코드에서 열거 형을 정적으로 정의하고 열거 형 사용의 모든 이점을 얻을 수 있습니다.


0

어떤 방식 으로든 동적 열거 형을 사용하는 것은 좋지 않습니다. 나중에 유지 관리하기 쉬운 명확하고 쉬운 코드를 보장하려면 데이터 "복제"문제를 겪어야합니다.

자동 생성 라이브러리를 도입하기 시작하면 단순히 열거 형을 적절한 클래스 개체 내에 코딩하는 것보다 코드를 업그레이드해야하는 미래의 개발자에게 더 많은 혼란을 야기 할 것입니다.

주어진 다른 예제는 멋지고 흥미롭게 들리지만 코드 유지 관리에 대한 오버 헤드와 그로부터 얻는 것에 대해 생각해보십시오. 또한 이러한 가치가 그렇게 자주 변경 될까요?


0

열거 형을 유지하고 동시에 값의 동적 목록을 만드는 한 가지 방법은 동적으로 생성 된 사전과 함께 현재 가지고있는 열거 형을 사용하는 것입니다.

대부분의 열거 형은 사용하도록 정의 된 컨텍스트에서 사용되며 "동적 열거 형"은 동적 프로세스에서 지원되므로 2를 구별 할 수 있습니다.

첫 번째 단계는 동적 항목에 대한 ID 및 참조를 포함하는 테이블 / 컬렉션을 만드는 것입니다. 표에서 가장 큰 Enum 값보다 훨씬 더 큰 자동 증가가 발생합니다.

이제 동적 열거 형에 대한 부분이 나옵니다. 규칙 집합을 적용하는 조건 집합을 만들기 위해 열거 형을 사용할 것이라고 가정하고 일부는 동적으로 생성됩니다.

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

열거 형 빌더 클래스

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.