关于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).
是否有更有效的编码风格?
您可以为每个枚举条目添加标准的 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框架中应用的体系结构和技术来解决非常类似的问题。
枚举非常适合在代码中工作,因为它们确实是强类型的,并且使重构更容易。按照以下步骤操作:
-
使用属性来附加到枚举上的任何额外信息。通常这是一个简单的
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>
与所有可能的代码,并根据代码名称或值找到特定的代码,只需在列表中搜索。