Is it possible to make an enum,with the contents which are read from database?

Locked Is it possible to make an enum,with the contents which are read from database?

  • Friday, April 13, 2012 3:26 PM
     
     

    Hi everyone,i know how to make a fixed enum like

    public enum test
            {
               
                qNone = 0,
                wFixedSingle = 1,
                eFixed3D = 2,
            }

    but i would like to ask is it possible that the enumerators are read from the database,that is to say,is it possible to make a unfixed enum?the enumerator in the enum can be decided according to the data in teh database? could anyone do me a kindness favor to help me? thank u very much in advance

    best regards

    martin

All Replies

  • Friday, April 13, 2012 3:33 PM
     
     Answered

    Check this link. Dynamic Enum Creation

    Thanks,


    Parth

    • Marked As Answer by martinwang1985 Monday, April 16, 2012 12:50 PM
    •  
  • Friday, April 13, 2012 3:33 PM
     
     Answered

    That's not possible, no.  The values of an Enumerator must be fixed at compile time.

    You might be thinking of a Dictionary, or a HashSet, if you have a set of valid values. (Dictionary if they map to ints or something else, HashSet if they don't.)

    • Marked As Answer by martinwang1985 Monday, April 16, 2012 12:49 PM
    •  
  • Friday, April 13, 2012 3:34 PM
     
      Has Code

    Enumerations were conceived as a nicer, language-level way to stop using #define macros.  You can possibly write something to generate an enumeration from a table in the database to help ease these things during development, but you have to have constants in the definition of an enum.  Now, if you wanted to make a static class with static public properties whose values are loaded at run time, this is doable in a fushion like this:

    public static class CategoryThing
    {
      private static int qNone;
      private static int qFixedSingle;
      private static int eFixed3D;
      static CategoryThing()
      {
        //Database read into a table
        qNone = (int)dt.FindRow("None");
        /etc
      }
      public static int None
      {
        get
        {
           return qNone;
        }
      }
      //And so on.
    }
    Now, you won't be able to use this as an enum in some things like a foreach loop, but this will get you some of the benefits like type checking and named constants.
  • Friday, April 13, 2012 3:48 PM
     
     

    hello.

    maybe the DLR match you need.

    you can create a class inherit from DynamicObject.

    take a look at DynamicObject Class at msdn .hope can help you.


    DON'T TRY SO HARD,THE BEST THINGS COME WHEN YOU LEAST EXPECT THEM TO.

  • Friday, April 13, 2012 3:51 PM
     
     

    Hi, servy42,

    thank u very much for ur response.

    now i am create an object and hope to bind to a propertygrid.

    i need that there could be sth like that

    public class myObject
            {

      public virtual status myStatus { get; set; }
    }

    and

    then

    public enum status
            {           
                None = 0,FixedSingle = 1,Fixed3D = 2,
            }

    but now i need that the combox can have more value from the database,i tried dictionary but that does not work

    best regards

    martin

  • Friday, April 13, 2012 4:00 PM
    Moderator
     
     Answered

    The whole purpose of an enum is to allow you to give literals nice (named constant) names to make code easier to read:

    int someType = 1;  //Poor
    DataType someType = DataType.Int;  //Better

    At runtime the behavior is the same and, furthermore, enums don't actually provide much more compile time validation than ints (you can still assign any int you want to an enum value).  There is a false sense of strong type checking with enums that doesn't actually exist.  C# is pretty good about warning you when you are misusing an enum but warnings can be ignored.

    If you have a list of values that are only available at runtime then an enum is not the best structure because you can't reference the values at compile time anyway.  A dictionary might work depending upon how you represent values.  If the names are compile time constants but the values are dynamic then a simple wrapper type that is exposed through a singleton or static class works just as well at runtime and gives you a semblance of enum functionality.

    Michael Taylor - 4/13/2012
    http://msmvps.com/blogs/p3net

    • Marked As Answer by martinwang1985 Monday, April 16, 2012 12:50 PM
    •  
  • Friday, April 13, 2012 4:07 PM
     
     

    Hi, CoolDadTx

    thank u very much for ur response.

    now i am create an object and hope to bind to a propertygrid.

    i need that there could be sth like that

    public class myObject
            {

      public virtual status myStatus { get; set; }
    }

    and

    then

    public enum status
            {           
                None = 0,FixedSingle = 1,Fixed3D = 2,
            }

    but now i need that the combox can have more value from the database,i tried dictionary but that does not work

    best regards

    martin
  • Friday, April 13, 2012 4:09 PM
     
     

    Using enums with unvalidated data that comes from the user, a file store, or the network is always a recipe for disaster.  Enums are great once you've thoroughly vetted the source value.  Some code somewhere must perform this validation.

  • Friday, April 13, 2012 4:52 PM
    Moderator
     
     Proposed Answer

    If you wanted to have a static set of enumerable-like values at compile time but want the actual numeric values to come at runtime (from a database) then something like this works:

    public static class test
    {
       public static int qNone { get; private set; }
       public static int wFixedSize { get; private set; }
       public static int eFixed3D { get; private set; }
    }

    Now you have an enumerator-like syntax:

    if (myType == test.qNone) ...

    To initialize the values you could either use a static constructor or an initialize method that queries the values from wherever.  This becomes part of your app init code.

    Michael Taylor - 4/13/2012
    http://msmvps.com/blogs/p3net

  • Friday, April 13, 2012 5:08 PM
     
     

    Hi,

    IMO if the values are static then you should use an enum but if you tell that values are coming from a database then it is likely that those values should be just thought as reference table inside your db. It doesn't prevent from gathering some known states if they are playing a role as part of some rules.


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • Saturday, April 14, 2012 3:36 AM
     
     Answered Has Code

    hi , martin

    for your purpose, you can create a class for combox item databinding.

        public class ItemData
        {
    
            public ItemData()
            {
    
            }
    
            public ItemData(int pId, string pName)
            {
                this.ID = pId;
                this.Name = pName;
            }
    
            public int ID { get; set; }
            public string Name { get; set; }
    
            public override string ToString()
            {
                return this.Name;
            }
        }

    and then .using List<ItemData> query from database binding to combox control

    finnally ,you Cast Combox.SelectedItem as ItemData to get the seleted ItemData instance.

    hope may help you something


    DON'T TRY SO HARD,THE BEST THINGS COME WHEN YOU LEAST EXPECT THEM TO.

    • Marked As Answer by martinwang1985 Monday, April 16, 2012 12:50 PM
    •  
  • Saturday, April 14, 2012 1:25 PM
     
     
    I believe that although it is quite likely you can create an enum via reflection, the cost of doing so would not be worth it. 
     
    What is the scenario where an enum is more efficient than the datasource itself?

    --
    Mike
  • Saturday, April 14, 2012 4:03 PM
    Moderator
     
     Answered Has Code

    I want to illustrate what an enumeration is in IL.  Enumerations are constants.  Enumerations are not static variables, fields or values.  They are fixed constant values.  Enumerations cannot be dynamically defined and used as such.  A disassembly of the IL demonstrates this.

        class MyEnumTest
        {
            public int Field = 0;
            public TestEnum UseTest(TestEnum test)
            {
                TestEnum te = TestEnum.eFixed3D;
                if ( test==TestEnum.qNone )
                {
                    int j = (int)test;
                }
                if ( Field == 21 )
                {
                    int j = Field;
                }
                return te;
            }
        }
        public enum TestEnum
        {
            qNone = 0,
            wFixedSingle = 1,
            eFixed3D = 2,
        }


    This produces the following IL..... first the enum definition, and then the method definition.  Notice the  word "literal".

    .class public auto ansi sealed TestEnum
        extends [mscorlib]System.Enum
    {
        .field public static literal valuetype Namespace.TestEnum eFixed3D = int32(2)
    
        .field public static literal valuetype Namespace.TestEnum qNone = int32(0)
    
        .field public specialname rtspecialname int32 value__
    
        .field public static literal valuetype Namespace.TestEnum wFixedSingle = int32(1)
    
    }
    .method public hidebysig instance valuetype NamespaceName.TestEnum 
            UseTest(valuetype TestEnum test) cil managed
    {
      // Code size       50 (0x32)
      .maxstack  2
      .locals init ([0] valuetype Namespace.TestEnum te,
               [1] int32 j,
               [2] valuetype TestEnum CS$1$0000,
               [3] bool CS$4$0001)
    
    //000012:         {
      IL_0000:  nop
    //000013:             TestEnum te = TestEnum.eFixed3D;
      IL_0001:  ldc.i4.2
      IL_0002:  stloc.0
    //000014:             if ( test==TestEnum.qNone )
      IL_0003:  ldarg.1
      IL_0004:  ldc.i4.0
      IL_0005:  ceq
      IL_0007:  ldc.i4.0
      IL_0008:  ceq
      IL_000a:  stloc.3
      IL_000b:  ldloc.3
      IL_000c:  brtrue.s   IL_0012
    //000015:             {
      IL_000e:  nop
    //000016:                 int j = (int)test;
      IL_000f:  ldarg.1
      IL_0010:  stloc.1
    //000017:             }
      IL_0011:  nop
    //000018:             if ( Field == 21 )
      IL_0012:  ldarg.0
      IL_0013:  ldfld      int32 MyEnumTest::Field
      IL_0018:  ldc.i4.s   21
      IL_001a:  ceq
      IL_001c:  ldc.i4.0
      IL_001d:  ceq
      IL_001f:  stloc.3
      IL_0020:  ldloc.3
      IL_0021:  brtrue.s   IL_002c
    //000019:             {
      IL_0023:  nop
    //000020:                 int j = Field;
      IL_0024:  ldarg.0
      IL_0025:  ldfld      int32 MyEnumTest::Field
      IL_002a:  stloc.1
    //000021:             }
      IL_002b:  nop
    //000022:             return te;
      IL_002c:  ldloc.0
      IL_002d:  stloc.2
      IL_002e:  br.s       IL_0030
    //000023:         }
      IL_0030:  ldloc.2
      IL_0031:  ret
    } // end of method MyEnumTest::UseTest

    Notice the lines of code where the If condition is evaluated in the IL, lines 0004 and 0013.  When the variable Field is loaded, a value is loaded from memory.  When the MyEnum value is loaded, a hard coded constant is used.  The Compiler knows the values are constant and will not change over the lifetime of the application, so it uses the value directly instead of fetching a value from somewhere in memory.  The values are stored as metadata, which other assemblies can read.

    Constants (C# Programming Guide) - MSDN – Explore Windows, Web ...

    "The enum type enables you to define named constants for integral built-in types (for example int, uint, long, and so on). For more information, see enum (C# Reference)."

    The point is that enumerations are not used as values stored in memory.  Enumeration values are used as hard coded constants within the assembly.  Can you define and create an enumeration dynamically?  Sure, but you would have to compile an assembly in order to use it.  I would use the above suggestion to create a static class with static variables.  Your code that consumed it would like identical to an enumeration.

    Hope this helps.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/




  • Monday, April 16, 2012 7:01 AM
     
     

    hi.thank u for all of u ur kindess help.i will now read them and try.thank u very much

    best regards

    martin

  • Monday, April 16, 2012 7:30 AM
     
     

    Hi Matthew,

    thank u very much for ur kindness help.

    but now i am required to use propertygridcontrol (in fact propertygridcontrol  of devexpress,it is more or less the same as ms propertygridcontrol).

    so there is a big object including some information and this object is binded to the propertygridcontrol.

    it is something like that:

     public class personinfo
            {           
                [Category("Name")]
                [DisplayName("Name")]
                public float length { get; set; }

                 [Category("Name")]
                [DisplayName("Surname")]
                public string name { get; set; }        


                [Category("Name")]
                [DisplayName("Surname")]
                public string surname{ get; set; }

                [Category("Chimiche")]
                [DisplayName("Material")]
                public string material { get; set; }

                [Category("Nation")]
                [DisplayName("Nation")]
                public virtual nationlist nation { get; set; }
            }

    the nationlist,now i design it as an enum,i hope that the content of this "nationlist" can be read from a database.

    then i will bind this personinfo to a propertygirdcontrol,so that in this propertygirdcontrol ,in item "nation"people can in choose from many countries read from db in the combo box

    now i am not sure if it is possible.

    anyway i appreciate ur help very much

    best regards

    martin

         

  • Monday, April 16, 2012 7:38 AM
     
     

    hi Matthew:

    the List u mean this:

    http://msdn.microsoft.com/en-us/library/3wcytfd1.aspx

    ?thank u very much

    best regards

    martin

  • Tuesday, April 17, 2012 7:12 AM
     
     

    Hi martinwang.

    for your purpose that show data in propertygrid control.

    you would assign a custom UTTypeEditor to you nationlist property .

    the custom UITypeEditor should do Dropdown action to show data list from database.

    you can reference below url

    http://msdn.microsoft.com/en-us/library/system.drawing.design.uitypeeditor.aspx

    good luck.


    DON'T TRY SO HARD,THE BEST THINGS COME WHEN YOU LEAST EXPECT THEM TO.

  • Tuesday, April 17, 2012 7:14 AM
     
     

    hi Matthew:

     thank u very much ur kindness help.i've resolved my problem

    best regards

    martin