在几个项目中,我们在数据库中有一个常量值列表。每个都有一个表,名称和GUID值。例如,故障单状态表可能有3个值,“打开”,“已关闭”和“保持”。在我们的C#代码中,框架生成一个C#文件,如下所示。
public class TicketStatus {
public static Guid Open = new Guid( "7ae15a71-6514-4559-8ea6-06b9ddc7a59a");
public static Guid Closed = new Guid( "41f81283-57f9-4bda-a03c-f632bd4d1628");
public static Guid Hold = new Guid( "41bcc323-258f-4e58-95be-e995a78d2ca8");
}; // end of TicketStatus
这允许我们编写一些干净的(ish)代码来设置故障单状态,如下所示 ticket.strStatus = TicketStatus.Open.ToString();
虽然这有效: - 它生成非常干净的C#代码,易于准备和维护 - 它受Intellisense支持
在那,它仍然很笨拙 - 我们必须不断转换为字符串以进行许多操作 - 使用GUID似乎有点矫枉过正。 - 我们不能写一个“正常”的开关语句// This won't compile
switch( strStatus ) {
case TicketStatus.Open:
case TicketStatus.Closed:
// do some stuff.
break;
}
代码最初是用一堆GUID实现的,用于管理数据库以全部大写形式返回值的情况。
问题:对这些常量值进行编码的最佳方法是什么,以便它支持IntelliSense和switch语句?
答案 0 :(得分:2)
谢谢Kirk, 这是我正在使用的字符串解决方案。
public static class TicketStatus {
public const string Open = "7ae15a71-6514-4559-8ea6-06b9ddc7a59a";
public const string Closed = "41f81283-57f9-4bda-a03c-f632bd4d1628";
public const string Hold = "41bcc323-258f-4e58-95be-e995a78d2ca8";
}; // end of TicketStatus
string strTemp = TicketStatus.Open;
switch (strTemp) {
case TicketStatus.Open:
strTemp = "Jackpot";
break;
}
答案 1 :(得分:1)
我确实认为,你应该尽可能坚持这一点。
public static class TicketStatus {
public const string Open = "7ae15a71-6514-4559-8ea6-06b9ddc7a59a";
public const string Closed = "41f81283-57f9-4bda-a03c-f632bd4d1628";
public const string Hold = "41bcc323-258f-4e58-95be-e995a78d2ca8";
}; // end of TicketStatus
有一个解决方案,没有人在这里提到过。您可以使用属性将自定义值分配给枚举。您需要定义一个属性和一些辅助类:
[AttributeUsage(AttributeTargets.Field)]
public class GuidValue : Attribute
{
public Guid Guid
{
get;
private set;
}
public GuidValue(Guid guid)
{
this.Guid = guid;
}
public GuidValue(string stringGuid)
{
this.Guid = new Guid(stringGuid);
}
}
public static class GuidBackedEnums
{
private static Guid GetGuid(Type type, string name)
{
return type.GetField(name).GetCustomAttribute<GuidValue>().Guid;
}
public static Guid GetGuid(Enum enumValue)
{
Type type = enumValue.GetType();
if (!type.IsEnum)
throw new Exception();
return GetGuid(type, enumValue.ToString());
}
public static T CreateFromGuid<T>(Guid guid)
{
Type type = typeof(T);
if (!type.IsEnum)
throw new Exception();
foreach (var value in Enum.GetValues(type))
{
if (guid == GetGuid(type, value.ToString()))
return (T)value;
}
throw new Exception();
}
}
然后您可以通过以下方式使用它:
enum TicketStatus
{
[GuidValue("7ae15a71-6514-4559-8ea6-06b9ddc7a59a")]
Open,
[GuidValue("41f81283-57f9-4bda-a03c-f632bd4d1628")]
Closed,
[GuidValue("41bcc323-258f-4e58-95be-e995a78d2ca8")]
Hold
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(GuidBackedEnums.CreateFromGuid<TicketStatus>(new Guid("41f81283-57f9-4bda-a03c-f632bd4d1628")));
Console.WriteLine(GuidBackedEnums.GetGuid(TicketStatus.Hold));
}
}
当然,TicketStatus是一个普通的枚举。所以你可以在switch语句中使用它。
答案 2 :(得分:0)
试试这个
public static Guid Open = new Guid("7ae15a71-6514-4559-8ea6-06b9ddc7a59a");
public static Guid Closed = new Guid("41f81283-57f9-4bda-a03c-f632bd4d1628");
public static Guid Hold = new Guid("41bcc323-258f-4e58-95be-e995a78d2ca8");
public enum Status1
{
Open,
Close,
Hold
}
public static Dictionary<Guid, Status1> Dic = new Dictionary<Guid, Status1>()
{
{Open , Status1.Open},
{Closed , Status1.Close},
{Hold , Status1.Hold}
};
然后
var a = TicketStatus.Closed;
var label = TicketStatus.Dic.FirstOrDefault(e => e.Key == a).Value;
switch (label)
{
case TicketStatus.Status1.Close:
}
让您的代码更具可读性
答案 3 :(得分:0)
我会使用类似java的枚举和一些反射。这是一个C#实现示例。我不能使用开关,但它会很快为您确定所需的对象。
using System;
using System.Reflection;
using System.Linq;
public class TicketStatus
{
private string _guid;
private TicketStatus(string guid)
{
_guid = guid;
}
public string GuidValue {get {return _guid; } }
public static readonly TicketStatus Open = new TicketStatus("7ae15a71-6514-4559-8ea6-06b9ddc7a59a");
public static readonly TicketStatus Closed = new TicketStatus("41f81283-57f9-4bda-a03c-f632bd4d1628");
public static readonly TicketStatus Hold = new TicketStatus("41bcc323-258f-4e58-95be-e995a78d2ca8");
//Reads all static readonly fields and selects the one who has the specified GUID
public static TicketStatus Identify(string guid)
{
var ticket = typeof(TicketStatus).GetFields()
.Where(x => (x.IsStatic == true) && (x.IsInitOnly == true) )
.Select(x => x.GetValue(null))
.SingleOrDefault(x => (x as TicketStatus).GuidValue == guid)
as TicketStatus;
return ticket;
}
}
public class Program
{
public static void Main()
{
var guid = "7ae15a71-6514-4559-8ea6-06b9ddc7a59a";
var ticket = TicketStatus.Identify(guid);
if(ticket != null)
{
Console.WriteLine(ticket.GuidValue + " found");
}
else
{
Console.WriteLine("unknown ticket");
}
}
}