根据情况,我有两种处理方法。
第一种是使用enum 和Dictionary<TKey, TValue> 将字符映射到enum 中的条目。
enum Priority : byte
{
High,
Medium,
Low
}
static class Priorities
{
private static Dictionary<char, Priority> _toPriority = new Dictionary<char, Priority>();
private static Dictionary<Priority, char> _fromPriority = new Dictionary<Priority, char>();
static Priorities()
{
var priorities = Enum.GetNames(typeof(Priority));
var values = (Priority[])Enum.GetValues(typeof(Priority));
for (var i = 0; i < priorities.Length; i++)
{
_toPriority.Add(priorities[i][0], values[i]);
_fromPriority.Add(values[i], priorities[i][0]);
}
}
public static Priority GetPriority(string field)
{
Priority res;
if (!TryGetPriority(field, out res))
throw new ArgumentException("Invalid priority on field.", "field");
return res;
}
public static bool TryGetPriority(string field, out Priority priority)
{
if (field == null || field.Length == 0) { priority = default(Priority); return false; }
return _toPriority.TryGetValue(field[0], out priority);
}
public static char GetCode(Priority priority)
{
return _fromPriority[priority];
}
}
另一种方法是创建一个struct,它在公共静态只读字段中创建自己。
struct Priority
{
public static readonly Priority High = new Priority('H');
public static readonly Priority Medium = new Priority('M');
public static readonly Priority Low = new Priority('L');
static Priority()
{
register(High);
register(Medium);
register(Low);
}
public static bool TryGetPriority(char code, out Priority priority)
{
return _map.TryGetValue(code, out priority);
}
public static Priority GetPriority(char code)
{
Priority priority;
if (!TryGetPriority(code, out priority))
throw new ArgumentException("Code doesn't represent an existing priority.", "code");
return priority;
}
public override int GetHashCode()
{
return _code.GetHashCode();
}
public override bool Equals(object obj)
{
if (!(obj is Priority)) return false;
return ((Priority)obj)._code == _code;
}
public override string ToString()
{
return _code.ToString();
}
public static implicit operator char(Priority @this) { return @this._code; }
public static explicit operator Priority(char code)
{
Priority result;
if (!_map.TryGetValue(code, out result))
throw new InvalidCastException();
return result;
}
private static readonly Dictionary<char, Priority> _map = new Dictionary<char, Priority>();
private static void register(Priority p)
{
_map.Add(char.ToLowerInvariant(p._code), p);
_map.Add(char.ToUpperInvariant(p._code), p);
}
private readonly char _code;
private Priority(char code) { _code = code; }
}
方法 1:
优点:您只需定义 enum,结果将自动更新。您可以访问全名 (enumInstance.ToString()) 和代码。
缺点:您需要显式调用转换方法才能在 char 和 Priority 之间进行切换。
方法 2:
优点: 该类型将隐式转换为 char,并且可以从 char 强制转换。
缺点: 您必须同时更新对register 和enum 的调用才能添加或修改条目。您无法访问该字段的全名。
方法二的两个缺点都可以轻松解决。第一个可以通过使用反射来发现所有公共字段来解决。第二个是通过将其作为参数添加到构造函数或也通过反射。
使用方法一:
Priority p = Priority.High; // Assign literal
MessageBox.Show(p.ToString()); // High
MessageBox.Show(Priorities.GetCode(p).ToString()); // H
Priority p = Priorities.GetPriority('L'); // Cast from character
MessageBox.Show(p.ToString()); // Low
MessageBox.Show(Priorities.GetCode(p).ToString()); // L
Priority p; // Safe assigning
if (!Priorities.TryGetPriority('M', out p))
return;
MessageBox.Show(p.ToString()); // Medium
MessageBox.Show(Priorities.GetCode(p).ToString()); // M
使用方法二:
Priority p = Priority.High; // Assign literal
MessageBox.Show(p.ToString()); // H
Priority p = (Priority)'L'; // Cast from character
MessageBox.Show(p.ToString()); // L
Priority p; // Safe assigning
if (!Priority.TryGetPriority('M', out p))
return; // Handle invalid scenario
MessageBox.Show(p.ToString()); // M
我个人认为这个解决方案比依赖两个开关和定义要干净得多。性能方面(除非你有一个非常大的数据库,否则它并不重要)它的执行与 switch 语句非常相似。正确条件下的 switch 语句将编译为代码内哈希图,就像 Dictionary<TKey, TValue> 是哈希图一样。
如果你想要多字符串,只需将char 更改为string。