关于enum更优雅的设计

本文关键字:enum 关于 | 更新日期: 2023-09-27 18:03:25

我正在学习c#。

我听说c#是最容易构造的语言之一。你们能让我的代码更优雅更高效吗?

public class ISO639
{
    public enum ISO639Code
    {
        Afrikaans,                      //af
        Albanian,                       //sq
        Amharic,                        //am
        ...
        Yiddish,                        //yi
        Unknown                         
    }

    public static string GetISO639CodeString(ISO639.ISO639Code l)
    {
        switch (l)
        {
            case ISO639Code.English: return "en";
            case ISO639Code.Japanese: return "ja";
            ...
            case ISO639Code.Hebrew: return "he";
            default: return "";
        }

    public static ISO639.ISO639Code GetISO39CodeValue(string s)
    {
        switch (s)
        {
            case "ko" : return ISO639Code.Korean;
            case "en" : return ISO639Code.English;
            ...
            case "hu" : return ISO639Code.Hungarian;
            default: return ISO639Code.Unknown;
        }
    }
}

这是我的ISO639级。这个类为ISO639代码提供枚举,但是我需要从ISO639枚举到普通字符串的类型转换。(前任ISO639.ISO639Code。意大利语=> "it")。我还需要从普通字符串到ISO639 enum的类型转换。(交货。"it" => ISO639.ISO639Code.Italian).

是否有更有效的编码风格?

关于enum更优雅的设计

您可以为每个枚举条目添加标准的 System.ComponentModel.Description属性,然后读取它。

public enum ISO639Code       
{ 
  [Description("af")]
  Afrikaans
}
public static class EnumExtensions
{
    // Extension method to read Description value
    public static string GetDescription(this Enum currentEnum)
    {
         var fi = currentEnum.GetType().GetField(currentEnum.ToString()); 
         var da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute)); 
         return da != null ? da.Description : currentEnum.ToString();
     } 
}
// **How-to read it**
ISO639Code isoCode = ISO639Code.Afrikaans;
// this will returns "af"
string isoDescription = isoCode.GetDescription(); 
编辑:

    string searchFor = "af"; 
    ISO639Code foundEntry;
    // Loop through all entries descriptions       
    var allEntries = Enum.GetValues(typeof(ISO639Code));
    foreach (var entry in allEntries)
    {
        // If you will extract this as separate method and use it for search not only loop
        // through the all entries - you can put here is yield return description
        var currentEntry = ((ISO639Code)entry);
        string description = currentEntry.GetDescription();
        if (description == searchFor)
        {
            foundEntry = currentEntry;
            break;
        }
    }

当然。你可以使用属性:

public enum ISO639Code
{
    [CodeString("af")] Afrikaans,
    [CodeString("sq")] Albanian,    
}

使用字典,例如:new Dictionary<ISO639Code, string> .

我建议你使用c#扩展方法来枚举,它们允许你添加任何你想要的逻辑。

例如:http://pietschsoft.com/post/2008/07/c-enhance-enums-using-extension-methods.aspx

我只是将信息存储在一个类似字典的对象中。通过这种方式,您可以通过键引用名称并直接获得值。

你有一个enum:

 public enum ISO639Code
 {
    Afrikaans = 1,                      
    Albanian  = 2,                       
    Amharic   = 3, 

等。

创建数据库表:

 ISO639Id   int   PK,
 ISO639Code char(2)

其中ISO639Id映射到enum的值。

在代码中,您需要一个包含从数据库读取的Id和code值的ISO630类。(你可以加载一次,然后缓存到内存中。)

这种方法的美妙之处在于它可以很容易地扩展,所以如果将来您想为每个ISO639代码存储更多的信息,您可以简单地添加另一个字段。

看看系统。Globailzation名称空间。您需要的功能看起来已经在那里实现了。在最坏的情况下,您可以看到在。net框架中应用的体系结构和技术来解决非常类似的问题。

枚举非常适合在代码中工作,因为它们确实是强类型的,并且使重构更容易。按照以下步骤操作:

  1. 使用属性来附加到枚举上的任何额外信息。通常这是一个简单的Description属性。比如:

    public enum IsoCodes{(描述(af))非洲人= 0;(描述("我"))美国人= 1}

然后编写一些扩展方法来将字符串和整数与此enum进行转换:

public static string GetDescription(this Enum value)
        {
            var entries = value.ToString().Split(FlagEnumSeparatorCharacter);
            var description = new string[entries.Length];
            for (var i = 0; i < entries.Length; i++)
            {
                var fieldInfo = value.GetType().GetField(entries[i].Trim());
                var attributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
                description[i] = (attributes.Length > 0) ? attributes[0].Description : entries[i].Trim();
            }
            return String.Join(", ", description);
        }
public static int GetValue(this Enum value)
    {
        return (int)value.GetType().GetField(value.ToString()).GetRawConstantValue();
    }
    public static T ToEnum<T>(this string value)
    {
        if (typeof(T).BaseType.Name != typeof(Enum).Name)
        {
            throw new Exception("Not an enum");
        }
        return (T)Enum.Parse(typeof(T), value, true);
    }
    public static T ToEnum<T>(this int value)
    {
        if (typeof(T).BaseType.Name != typeof(Enum).Name)
        {
            throw new Exception("Not an enum");
        }
        return (T)Enum.ToObject(typeof(T), value);
    }

现在可以随意使用枚举了

我会用ISO639Code作为类而不是enum:

public class ISO639Code
{
    public string Value { get; set ; }
    public string Code { get; set; }
    public ISO639Code()
    {
        this.Value = "";
        this.Code = "";
    }
    public ISO639Code(string value, string code)
        : this()
    {
        this.Value = value;
        this.Code = code;
    }
    public override bool Equals(object obj)
    {
        if (obj != null)
        {
            if (obj is string)
                return obj.ToString().Equals(this.Value, StringComparison.CurrentCultureIgnoreCase);
            if (obj is ISO639Code)
                return ((ISO639Code)obj).Value.Equals(this.Value, StringComparison.CurrentCultureIgnoreCase);
        }
        return false;
    }
    public override int GetHashCode()
    {
        return this.Value.GetHashCode();
    }
    public override string ToString()
    {
        return this.Value;
    }
}

然后有全局List<ISO639Code>与所有可能的代码,并根据代码名称或值找到特定的代码,只需在列表中搜索。