Enum support

2010-03-22
2013-04-25
  • Alexandre FAU
    Alexandre FAU
    2010-03-22

    Dpm11 have thak kind of enum in his project :

    public enum Specification
    {
      V01R01_1("V01R01.1");
      V01R01_2("V01R01.2");
      V01R01_3("V01R01.3");
      V01R01_4("V01R01.4");
      V01R01_5("V01R01.5");

      private final String description;

      private Specification(String description)
      {
        this.description = description;
      }

      public String getDescription()
      {
        return this.description;
    }

      public static final Specification find(String desc)
      {
        return descToSpec.get(desc);
      }

      private static final Map<String, Specification> descToSpec;

      static
      {
        descToSpec = new HashMap<String, Specification>();
        for (Specification spec : values())
        {
          descToSpec.put(spec.getDescription(), spec);
        }
      }
    }

    I suggest that a possible translation could be :

    public enum Specification
    {
      V01R01_1,
      V01R01_2,
      V01R01_3,
      V01R01_4,
      V01R01_5
    }

    public static class SpecificationExt
    {
       static IDictionary<E, String> map = new Dictionary<E, string>();

      public static void Build(this E en, String descr)
      {
        map = descr;
      }

      public static String GetDescription(this E en)
      {
      return map;
      }

      private static final Map<String, Specification> descToSpec;

      public static final Specification Find(String desc)
      {
        return descToSpec;
      }

      static SpecificationExt()
      {
        Specification.V01R01_1.Build("V01R01.1");
        Specification.V01R01_2.Build("V01R01.2");
        Specification.V01R01_3.Build("V01R01.3");
        Specification.V01R01_4.Build("V01R01.4");
        Specification.V01R01_5.Build("V01R01.5");
        //
        // How to port that o .NEt ???
        descToSpec = new HashMap<String, Specification>();
        for (Specification spec : Enum.GetValues(typeof(Specification)))
        {
          descToSpec.put(spec.GetDescription(), spec);
        }
      }
    }

    For sure this will be hard to implement in the general case …

    @

     
  • Benjamin
    Benjamin
    2010-03-23

    Hi,

    I actually had the same dort of translation to do and I implemented something like that. It seems to work well enought in the general case. It translate "complex" java enum, in C# class implementing the same method as enumeration

    It translate this :

    public enum Type
        {
            A_MARKS(leon.misc.LyBitSet.class),
            F_MARKS(leon.misc.LyBitSet.class),
            FILTER(leon.info.LyFilter.class);
            
            Class   _typeClass;
            
            Type(Class typeClass)
            {
                _typeClass = typeClass;
            }
            
            Class getTypeClass()
            {
                return _typeClass;
            }
        }
    

    into this :

    public class Typ {
            public static readonly Typ A_MARKS = new Typ(typeof(leon.misc.LyBitSet), "A_MARKS", 0);
            public static readonly Typ F_MARKS = new Typ(typeof(leon.misc.LyBitSet), "F_MARKS", 1);
            public static readonly Typ FILTER = new Typ(typeof(leon.info.LyFilter), "FILTER", 2);
                    14);
            Type _typeClass;
      
            private Typ(Type typeClass, String j2cs_name,
                    int j2cs_ordinal) {
                _typeClass = typeClass;
                __j2cs__Name = j2cs_name;
                __j2cs__Ordinal = j2cs_ordinal;
            }
      
            public Type GetTypeClass() {
                return _typeClass;
            }
      
            public override String ToString() {
                return __j2cs__Name;
            }
      
            public static readonly int __j2cs__ComplexEnum;
            private static Typ[] __j2cs__Constants = { A_MARKS, F_MARKS, FILTER };
      
            public static Typ[] Values() {
                return __j2cs__Constants;
            }
      
            public static Typ ValueOf(String type) {
                switch (type) {
                case "A_MARKS":
                    return A_MARKS;
                case "F_MARKS":
                    return F_MARKS;
                case "FILTER":
                    return FILTER;
                }
                return null;
            }
      
            int __j2cs__Ordinal;
      
            public int Ordinal() {
                return __j2cs__Ordinal;
            }
      
            String __j2cs__Name;
      
            public String Name() {
                return __j2cs__Name;
            }
      
            public int CompareTo(Typ l_enum) {
                return Ordinal() - l_enum.Ordinal();
            }
        }
    

    Then to ensure compatibility with java when using Enum static method, I use my own Enum class :

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Reflection;
    using System.Collections;
    namespace W4.J2CsMapping.Lang
    {
        /// <summary>
        /// Given a type, Enum or Class, return the object associate to the string
        /// Unlike Java, .Net doesn't allow "complexe" enumeration, so a few java enumeration
        /// has been translate into classes. This classe allow us to use them as if they were all 
        /// enumeration.
        /// </summary>
        public class LyCsEnum
        {
            /// <summary>
            /// Return the object associate to the string value within 
            /// enumType
            /// </summary>
            /// <param name="enumType">The type containing the string value</param>
            /// <param name="value">The string value representing the type within the enum</param>
            /// <returns></returns>
          public static T Parse<T>(Type a_enumType, string a_value)
           {
             if (a_enumType.IsEnum)
             {
               return (T)Enum.Parse(a_enumType, a_value);
             }
             else
             {
               try
               {
                 MethodInfo method = a_enumType.GetMethod("ValueOf");
                 return (T)method.Invoke(null, new object[] { a_value });
               }
               catch (TargetException)
               {
                 Console.Error.WriteLine(a_enumType + " is not an enumeration");
                 return default(T);
               }
             }
            }
          public static object Parse(Type a_enumType, string a_value)
          {
            if (a_enumType.IsEnum)
            {
              return Enum.Parse(a_enumType, a_value);
            }
            else
            {
              try
              {
                MethodInfo method = a_enumType.GetMethod("ValueOf");
                return method.Invoke(null, new object[] { a_value });
              }
              catch (TargetException)
              {
                Console.Error.WriteLine(a_enumType + " is not an enumeration");
                return null;
              }
            }
          }
          public static int Ordinal(Type a_enumType, object a_value)
          {
            if (a_enumType.IsEnum)
            {
              return (int)a_value;
            }
            else
            {
              try
              {
                MethodInfo l_method = a_enumType.GetMethod("Ordinal");
                return (int)l_method.Invoke(a_value, null);
              }
              catch (TargetException)
              {
                Console.Error.WriteLine(a_enumType + " is not an enumeration");
                return -1;
              }
            }
          }
          public static T[] Values<T>(Type a_enumType)
          {
            if (a_enumType.IsEnum)
            {
              return (T[])Enum.GetValues(a_enumType);
            }
            else
            {
              try
              {
                MethodInfo l_method = a_enumType.GetMethod("Values");
                return (T[])l_method.Invoke(null, null);
              }
              catch (TargetException)
              {
                Console.Error.WriteLine(a_enumType + " is not an enumeration");
                return null;
              }
            }
          }
          public static Array Values(Type a_enumType)
          {
            if (a_enumType.IsEnum)
            {
              
              return Enum.GetValues(a_enumType);
            }
            else
            {
              try
              {
                MethodInfo l_method = a_enumType.GetMethod("Values");
                return (Array)l_method.Invoke(null, null);
              }
              catch (TargetException)
              {
                Console.Error.WriteLine(a_enumType+" is not an enumeration");
                return null;
              }
              catch (NullReferenceException)
              {
                return null;
              }
            }
          }
        }
    }
    

    It can seam a little barbarian, but it's the only way I found to go around the issue

    Benjamin

     
  • Benjamin
    Benjamin
    2010-03-23

    Sorry about the presentation, the code mark don't seem to work…

    benjamin