管理常量列表

本文关键字:列表 常量 管理 | 更新日期: 2023-09-27 18:05:09

在几个项目中,我们在数据库中有一个常量值列表。它们每个都有一个表、名称和GUID值。例如,票证状态表可能有3个值,"Open","Closed"answers"Hold"。在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

这允许我们编写一些简洁的代码来设置票据状态,如下所示票。strStatus = TicketStatus.Open.ToString();

当它工作时:-它生成非常干净的c#代码,易于准备和维护智能感知

支持

它仍然很笨拙-在许多操作中,我们必须不断地转换为字符串- guid的使用似乎有些过度。-我们不能写一个"正常"的开关语句

// This won't compile
        switch( strStatus ) {
        case TicketStatus.Open:
        case TicketStatus.Closed:
        // do some stuff.
        break;
        }

代码最初是用一堆guid实现的,以管理数据库将返回所有大写值的情况。

问题:什么是最好的方式来编码这些常量值,使它支持智能感知和开关语句?

管理常量列表

谢谢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;
}

序言

我真的认为,你应该尽可能地坚持下去。

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

如果你想要一些魔法:)

有一个解决办法,这里没有人提到。可以使用属性将自定义值分配给枚举。您需要定义一个属性和一些helper类:

[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是一个普通enum。所以你可以在switch语句中使用它

我将使用类似java的enum和一些反射。下面是一个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");
        }
    }
}

try this

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:
}

让你的代码更容易读