.NET下枚举类型的Save和Load分析
来源:互联网 发布:中国言论自由 知乎 编辑:程序博客网 时间:2024/06/03 22:55
今天在写代码的时候,心血来潮对原来的字符串保存状态位的方式很不满意,对于代码里出现了 state == "1" 这样的状态判断很是不爽。那么理想中的判断是怎样的呢?很简单如你所想枚举类型。
public enum FormSate{ View, Modify}State == FormSate.View;和"1"这样的硬代码比较起来,上面的代码看起来可读性很强。
.NET 枚举的应用分析
接下来,自然而然的会出现在ORM操作中,对于一个数据Model,我们需要与数据库打交道,那么它该怎么保存,又该保存为什么数据类型?首先该说说Enum对应的是什么基本类型?在.NET里,一个枚举类型默认是一个int,且默认是从0开始的,除非指定。(这里不探讨Enum的深入用法和语法分析)上面的代码实际上被定义为如下的格式。public enum FormSate{ View = 0, Modify = 1}这样我们可以对一个枚举类进行基本的比较运算等等,比如"FormSate.View > FormSate.Mofiy"这样的比较。因此我们保存的时候就可以以int格式保存在数据库中。而读取的时候int是可以直接赋值给enum类型的,不过这里需要注意下的是这个赋值可不是用"="去赋值,而是反射SetValue。如果都用了"="号去赋值,我想肯定没用ORM,那么用一下的语句手动赋值。
Enum.Parse(typeof(FormSate), "1");
如果是用的ORM,大概都有提供对Enum的处理,看下API即可,不过原理大概都是反射,类似一下代码:public class MyEnumClass{ public FormSate _a { get; set; } }var b = new MyEnumClass();var p = b.GetType().GetProperties().FirstOrDefault();p.SetValue(b, 1, null);
枚举的自定义格式存储
在我的项目为例有这样的情况,所有状态位都是保存为varchar类型,会用"T"代表"True","F"代码"False"这样的存储,这时候需要改动上边的实现。首先,需要把数据库里的字段格式改为varchar,然后我们改动下枚举public enum ResultState{ T = 0,//sucess F = 1//failed}这样的处理好意疑问没啥问题,可是代码的可读性变差了,从缩写上很难读懂。于是我们可以这样处理
public enum ResultState{ [Description("true")] T = 0,//sucess [Description("false")] F = 1//failed}给枚举值加上Description标签,用于解释属性的意思。这样做还是不能在引用这个枚举的时候见字就理解意思,只能找到定义查看。那么,或许咱们可以改造为从Description标签读取保存的信息?这样做的话,还可以充分的自定义,可以保存为任何我们想要的格式。
public enum ResultState{ [Description("T")] SUCCESS = 0,//sucess [Description("F")] FAILED = 1//failed}
然后我们需要在读写ResultState的时候,进行反射。
public static class MyEnumExtensions{ public static string ToDescriptionString(this Enum val) { var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false); return attributes.Length > 0 ? attributes[0].Description : string.Empty; }}
这里写了一个Enum类的扩展方法(什么是扩展方法?)ToDescriptionString对Enum扩展了取到Description标签内容的方法。利用了反射,对于反射的性能什么的,我只想说该用还是用,除非真的很看中那几毫秒的性能。
b._a.ToDescriptionString();
这样改造之后,对于数据库的读写部分,还是要进行改造,具体的思路和上面的常规思路一样,要么手动,要么在做ORM层的时候,对Enum进行特殊处理。不过这里我有一点点想法,自定义一个Attibute标签用于指示,如何处理Enum类型,这样对于每
种需求场景都可以自由的扩展和选择
public enum EnumOpration{ ByDescription,//利用Description标签 Default,//默认的数字存储 ByName//默认的存储属性名}public class MyEnumClass{ [EnumElement(opration = EnumOpration.ByName, DBType = DbType.String)] public FormSate _a { get; set; } }
这里opration指示了枚举取什么值保存,而DBType则指示保存的数据类型,当让要实现这一整套的机制,在ORM做Mapping的时候需要做很多工作,这里就不给出具体实现了。
枚举的另类替代方法
如何了解Java的肯定知道Java里是没有枚举的,那么该如何实现?.NET下这样的实现方式是否有可取之处呢?我转载了 Stackoverflow上的一个回答,建议大家观摩下,猛击这里
public class LogCategory{ private LogCategory(string value) { Value = value; } public string Value { get; set; } public static LogCategory Trace { get { return new LogCategory("Trace"); } } public static LogCategory Debug { get { return new LogCategory("Debug"); } } public static LogCategory Info { get { return new LogCategory("Info"); } } public static LogCategory Warning { get { return new LogCategory("Warning"); } } public static LogCategory Error { get { return new LogCategory("Error"); } }}public static void Write(string message, LogCategory logCategory){ var log = new LogEntry { Message = message }; Logger.Write(log, logCategory.Value);}Usage:Logger.Write("This is almost like an enum.", LogCategory.Info);不过这样的实现有个比较大的问题,数据存储的时候,需要做些工作不仅要反射出实体对象,还要用枚举属性的类型去反射创建枚举对象再赋值,不过也只是复杂了一步而已。
总结
以上便是今天我在看到枚举的时候想到的一些问题,可能大家会说都是废话,完全不需要想这么多。遇到枚举最简单的Save和Load方法还是直接保存int类型的值,这样省时省力。不过在遇到一些特殊的情况的时候,我想上面的自定义方式,也许对你有些帮助。如果以上有什么不对的地方,请指正。
我的独立博客地址:http://www.capqueen.name,欢迎交流。
- .NET下枚举类型的Save和Load分析
- matlab 的load和save
- Tensorflow的save和load
- Julia : 再谈HDF5 的save 和 load
- save和load
- 深入分析 ASP.NET Mvc 1.0 – 2. Controller.Execute(Request)-TempDataDictionary的Load与Save操作
- matlab中save和load
- numpy.load和numpy.save
- Opencv关于PNG图像的load和save问题
- Hibernate的OID,对象状态,save(),saveOrUpdate(),get()和load()
- java中枚举类型enum的使用和分析
- 枚举类型在Linux和Windows下编程的区别
- Docker image批量save和load
- sklearn 模型持久化,save和load
- PyTorch笔记5-save和load神经网络
- 枚举类型Enum的含义分析
- 【深度分析】Java的枚举类型
- Julia: save 和load的用法 和与Matlab的效率比较
- 视频格式的转换
- Unix学习笔记(1)
- 从C/C++到Python(之二)(By Robinvane Suen)
- contextServlet
- 生成Maven骨架(archetype)
- .NET下枚举类型的Save和Load分析
- POI中设置Excel单元格格式
- uva 10132 File Fragmentation(检索)
- iPad for iPhone Developers 101 in iOS 6: UISplitView Tutorial
- 程序员困境:底层编码能力正逐步丧失
- C++的类型转换符
- Django开发demo
- 安装Dropbox必配小工具
- 聚合类型结构体