我正在构建一个大量使用Enum
s用于自定义数据的应用程序。实质上,对象存储在数据库中,具有大约28个单独的属性。每个属性都是一个双字符字段,从SQL直接转换为Enum
。
不幸的是,我还需要将这些值转换为两个不同的人类可读值。一个用于数据表上的图例,另一个用于CSS类,用于在Web应用程序前端设置图像样式。
为此,我设置了两个自定义属性,并在必要时将其应用于Enum
。例如:
自定义属性界面
public interface IAttribute<T>
{
T Value { get; }
}
自定义属性示例
public sealed class AbbreviationAttribute: Attribute, IAttribute<string>
{
private readonly string value;
public AbbreviationAttribute(string value)
{
this.value = value;
}
public string Value
{
get { return this.value; }
}
}
从Enum
public static R GetAttributeValue<T, R>(IConvertible @enum)
{
R attributeValue = default(R);
if (@enum != null)
{
FieldInfo fi = @enum.GetType().GetField(@enum.ToString());
if (fi != null)
{
T[] attributes = fi.GetCustomAttributes(typeof(T), false) as T[];
if (attributes != null && attributes.Length > 0)
{
IAttribute<R> attribute = attributes[0] as IAttribute<R>;
if (attribute != null)
{
attributeValue = attribute.Value;
}
}
}
}
return attributeValue;
}
示例Enum
使用此模式
public enum Download
{
[Abbreviation("check")]
[Description("Certified")]
C = 1,
[Abbreviation("no-formal")]
[Description("No formal certification")]
NF = 2,
[Abbreviation("cert-prob")]
[Description("Certified with potential problems")]
CP = 3
}
Abbreviation
和Description
都是实现IAttribute<T>
的自定义属性。我的实际Enum
有11个可能的值,正如我之前提到的,它在我的自定义对象中的28个单独属性中使用。使用自定义属性似乎是来回映射此信息的最佳方式。
现在提出问题,这是实现此目的的最佳方法吗?我将Enum
值(“C”,“NF”或“CP”存储在上面的代码段中)在数据库中,但我需要在我的代码中的缩写和描述的值。另外,我怀疑这将是我需要的最后一组自定义属性。
在我继续推进这种模式之前... 这是正确的做事方式吗?我宁愿用这种方法修复潜在的问题,而不是后来追踪和重构。
答案 0 :(得分:15)
这与我使用的方法相同。一个缺点是序列化。自定义属性值不会序列化。
我喜欢数据库方法的自定义属性方法,因为它将属性数据绑定到枚举,而不必使用查找表或类等。
答案 1 :(得分:2)
我可能会为这样的东西构建一个哈希表和一个特殊类型。你可能因为某种原因已经放弃了这个想法,但这就是我不知道你的应用程序的具体细节。
class SpecialType {
// include the fields and all attributes that you need to reference, ToString method for debugging, and any serialization you need
public string foo { get; set; }
public string bar { get; set; }
public ToString() { return "SpecialType with foo '" + foo + "' and bar '" + bar + "'"; }
}
Dictionary<int, SpecialType> myDict = new Dictionary<int, SpecialType> {
{ 1, new SpecialType { foo = "XA1B2", bar = "XC3D4" } },
{ 2, new SpecialType { foo = "ZA1B2", bar = "ZC3D4" } },
{ 3, new SpecialType { foo = "YA1B2", bar = "YC3D4" } },
}
然后我可以轻松地在我的其他类中保持内存以节省内存,通过检查字典键中的存在来查明特定值是否有效,所有爵士乐。如果您最终要使用WPF或读/写磁盘,那么进行数据绑定可能要容易得多。
答案 2 :(得分:1)
你可以改变数据库吗?我认为最好的选择是创建一个表(或表)来容纳枚举的可能值和主要对象的外键(而不是使用char代码 - 这使得更容易拉动它并使数据库规范化) 。为表格提供Abbreviation
和Description
列,然后将其拉入并按键引用它们,如果查找速度很慢,则将其缓存。
关于这些属性的一个危险是,如果这些字符串中的任何一个必须改变,那么它就是对应用程序的完全重新部署。如果您将它们设为数据库值,则可以使用简单的UPDATE
更改它们。