Enum ToString with user friendly strings

后端 未结 23 1741
伪装坚强ぢ
伪装坚强ぢ 2020-11-22 11:44

My enum consists of the following values:

private enum PublishStatusses{
    NotCompleted,
    Completed,
    Error
};

I want to be able to

相关标签:
23条回答
  • 2020-11-22 12:31

    The easiest solution here is to use a custom extension method (in .NET 3.5 at least - you can just convert it into a static helper method for earlier framework versions).

    public static string ToCustomString(this PublishStatusses value)
    {
        switch(value)
        {
            // Return string depending on value.
        }
        return null;
    }
    

    I am assuming here that you want to return something other than the actual name of the enum value (which you can get by simply calling ToString).

    0 讨论(0)
  • 2020-11-22 12:31

    According to this documentation: https://docs.microsoft.com/pt-br/dotnet/api/system.enum.tostring?view=netframework-4.8

    It is possible to just convert a enumerator to string using a format like this:

    public enum Example
    {
        Example1,
        Example2
    }
    
    Console.WriteLine(Example.Example1.ToString("g"));
    
    //Outputs: "Example1"
    

    You can see all the possible formats in this link: https://docs.microsoft.com/pt-br/dotnet/api/system.string?view=netframework-4.8

    0 讨论(0)
  • 2020-11-22 12:31

    In case you just want to add a whitespace between the words, it is as simple as

    string res = Regex.Replace(PublishStatusses.NotCompleted, "[A-Z]", " $0").Trim();
    
    0 讨论(0)
  • 2020-11-22 12:32

    I do this with extension methods:

    public enum ErrorLevel
    {
      None,
      Low,
      High,
      SoylentGreen
    }
    
    public static class ErrorLevelExtensions
    {
      public static string ToFriendlyString(this ErrorLevel me)
      {
        switch(me)
        {
          case ErrorLevel.None:
            return "Everything is OK";
          case ErrorLevel.Low:
            return "SNAFU, if you know what I mean.";
          case ErrorLevel.High:
            return "Reaching TARFU levels";
          case ErrorLevel.SoylentGreen:
            return "ITS PEOPLE!!!!";
          default:
            return "Get your damn dirty hands off me you FILTHY APE!";
        }
      }
    }
    
    0 讨论(0)
  • 2020-11-22 12:32

    Some other more primitive options that avoid classes/reference types:

    • Array method
    • Nested struct method

    Array method

    private struct PublishStatusses
    {
        public static string[] Desc = {
            "Not Completed",
            "Completed",
            "Error"
        };
    
        public enum Id
        {
            NotCompleted = 0,
            Completed,
            Error
        };
    }
    

    Usage

    string desc = PublishStatusses.Desc[(int)PublishStatusses.Id.Completed];
    

    Nested struct method

    private struct PublishStatusses
    {
        public struct NotCompleted
        {
            public const int Id = 0;
            public const string Desc = "Not Completed";
        }
    
        public struct Completed
        {
            public const int Id = 1;
            public const string Desc = "Completed";
        }
    
        public struct Error
        {
            public const int Id = 2;
            public const string Desc = "Error";
        }            
    }
    

    Usage

    int id = PublishStatusses.NotCompleted.Id;
    string desc = PublishStatusses.NotCompleted.Desc;
    

    Update (03/09/2018)

    A hybrid of Extension Methods and the first technique above.

    I prefer enums to be defined where they "belong" (closest to their source of origin and not in some common, global namespace).

    namespace ViewModels
    {
        public class RecordVM
        {
            //public enum Enum { Minutes, Hours }
            public struct Enum
            {
                public enum Id { Minutes, Hours }
                public static string[] Name = { "Minute(s)", "Hour(s)" };
            }
        }
    }
    

    The extension method seems suited for a common area, and the "localized" definition of the enum now makes the extension method more verbose.

    namespace Common
    {
        public static class EnumExtensions
        {
            public static string Name(this RecordVM.Enum.Id id)
            {
                return RecordVM.Enum.Name[(int)id];
            }
        }   
    }
    

    A usage example of the enum and it's extension method.

    namespace Views
    {
        public class RecordView 
        {
            private RecordDataFieldList<string, string> _fieldUnit;
    
            public RecordView()
            {
                _fieldUnit.List = new IdValueList<string, string>
                {            
                    new ListItem<string>((int)RecordVM.Enum.Id.Minutes, RecordVM.Enum.Id.Minutes.Name()),
                    new ListItem<string>((int)RecordVM.Enum.Id.Hours, RecordVM.Enum.Id.Hours.Name())
                };
            }
    
            private void Update()
            {    
                RecordVM.Enum.Id eId = DetermineUnit();
    
                _fieldUnit.Input.Text = _fieldUnit.List.SetSelected((int)eId).Value;
            }
        }
    }
    

    Note: I actually decided to eliminate the Enum wrapper (and Name array), since it's best that the name strings come from a resource (ie config file or DB) instead of being hard-coded, and because I ended up putting the extension method in the ViewModels namespace (just in a different, "CommonVM.cs" file). Plus the whole .Id thing becomes distracting and cumbersome.

    namespace ViewModels
    {
        public class RecordVM
        {
            public enum Enum { Minutes, Hours }
            //public struct Enum
            //{
            //    public enum Id { Minutes, Hours }
            //    public static string[] Name = { "Minute(s)", "Hour(s)" };
            //}
        }
    }
    

    CommonVM.cs

    //namespace Common
    namespace ViewModels
    {
        public static class EnumExtensions
        {
            public static string Name(this RecordVM.Enum id)
            {
                //return RecordVM.Enum.Name[(int)id];
                switch (id)
                {
                    case RecordVM.Enum.Minutes: return "Minute(s)";                    
                    case RecordVM.Enum.Hours: return "Hour(s)";
                    default: return null;
                }
            }
        }   
    }
    

    A usage example of the enum and it's extension method.

    namespace Views
    {
        public class RecordView 
        {
            private RecordDataFieldList<string, string> _fieldUnit
    
            public RecordView()
            {
                _fieldUnit.List = new IdValueList<string, string>
                {            
                    new ListItem<string>((int)RecordVM.Enum.Id.Minutes, RecordVM.Enum.Id.Minutes.Name()),
                    new ListItem<string>((int)RecordVM.Enum.Id.Hours, RecordVM.Enum.Id.Hours.Name())
                };
            }
    
            private void Update()
            {    
                RecordVM.Enum eId = DetermineUnit();
    
                _fieldUnit.Input.Text = _fieldUnit.List.SetSelected((int)eId).Value;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:33

    You can use Humanizer package with Humanize Enums possiblity. An eaxample:

    enum PublishStatusses
    {
        [Description("Custom description")]
        NotCompleted,
        AlmostCompleted,
        Error
    };
    

    then you can use Humanize extension method on enum directly:

    var st1 = PublishStatusses.NotCompleted;
    var str1 = st1.Humanize(); // will result in Custom description
    
    var st2 = PublishStatusses.AlmostCompleted;
    var str2 = st2.Humanize(); // will result in Almost completed (calculated automaticaly)
    
    0 讨论(0)
提交回复
热议问题