[置顶] .NET下枚举类型的Save和Load分析

时间:2021-01-17 23:51:23

今天在写代码的时候,心血来潮对原来的字符串保存状态位的方式很不满意,对于代码里出现了 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下这样的实现方式是否有可取之处呢?我转载了 *上的一个回答,建议大家观摩下,猛击这里

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分析的更多相关文章

  1. [置顶] Linux下文件和目录权限说明

    在Linux下使用ls -l或者ll命令可以查看文件和文件夹的权限.结果显示类似于: drwxrwxrwx,这里分为四组,分别为文件类型,文件所有者的权限(读写执行),文件所有者所在组用户的权限(读写 ...

  2. [置顶] Linux下的截图小工具

    Linux下的截图工具scrot 基于命令行 先下载:scrot apt-get install scrot 对该工具的操作: 分为以下几个部分 1.抓取整个桌面 scrot pic.jpg 2.抓取 ...

  3. [置顶] linux下让php支持mysql——寻找消失的mysql

       问题 最近我都在忙一个课件录制系统.这两天发现其中服务器端的一个更新数据库的php脚本运行有问题,一些本应该是系统自带函数却无法运行.于是我展开了调查... 服务器端是centos系统,其中ph ...

  4. [置顶] MyEclipse下安装插件方法(properties文件编辑器Propedit为例)

    网上流传了很多安装插件的方法.在这里我只讲解一种方法. 因为我认为这种方法有以下两个优点:第一.简单,方便安装:第二.对于自己安装的插件易于管理. 我的myeclipse版本号为10.5,操作系统为w ...

  5. [置顶] Android下实现自动关机的方法总结

    最近在网上看了一些Android下实现自动关机的方法,有的不行,有的只适用一些机型,有的适用于大部分机型,笔者在此总结一下 法一: Intent newIntent = new Intent(Inte ...

  6. [置顶] ARM-Linux下WEB服务器Boa的移植、配置和运行测试

    Linux下使用的轻量级WEB服务器主要有:lighttpd.thttpd.shttpd和boa等等,而Boa是使用最为广泛的轻量级WEB服务器之一(当然,阿帕奇是世界使用排名第一的Web服务器软件) ...

  7. [置顶] Linux下发布QT程序

    Linux下发布QT程序 概述 无论在windows下还是在linux下,可执行程序的运行都依赖于相关的运行库,我们需要将依赖的库找到放到特定的位置,让可执行文件能够找到.在不知道可执行文件依赖哪些库 ...

  8. [置顶] Linux下将Nutch1.3导入eclipse

    1.准备工作 首先去官网下载好 apache-nutch-1.3-bin.zip 解压apache-nutch-1.3-bin.zip [pig@CentOs ]$ unzip   apache-nu ...

  9. SCXcodeSwitchExpander自动填充switch语句下枚举类型case

    下载地址:https://github.com/stefanceriu/SCXcodeSwitchExpander 跟VVDocumenter规范注释生成器的安装方式一样: 下载开源工程在Xcode重 ...

随机推荐

  1. iOS 8.0后使用UIAlertController

    iOS 8的新特性之一就是让接口更有适应性.更灵活,因此许多视图控制器的实现方式发生了巨大的变化.全新的UIPresentationController在实现视图控制器间的过渡动画效果和自适应设备尺寸 ...

  2. [HTML]JS全屏代码

    video全屏参考:https://www.thecssninja.com/javascript/fullscreen <!doctype html> <html> <h ...

  3. Ztree使用笔记

    在项目中需要用到树,使用了Ztree.(官网地址:http://www.treejs.cn/v3/main.php#_zTreeInfo,介绍很详细,有API,有demo) 1.初始化树:   $.f ...

  4. Event 讲解

    应用场景:某件事发生时,需要采取多步的动作,此时就用到了 使用方法:创建event方法一,使用命令 make:event  生成事件在app/Events目录下,命令make:listener 生成监 ...

  5. Effective Modern C&plus;&plus;翻译&lpar;1&rpar;:序言

    /*********************************************************** 关于书: 书是我从网上找到的effective Modern C++的样章,内 ...

  6. &lbrack;Django&rsqb;models定义choices 字典中的页面显示值

    问题: 在django的models.py 在.我们定义一些choices元组,类别似一些字典值.通常下拉框或单个复选框,例如 0相应的M 1妇女和其他有关 class Area(models.Mod ...

  7. 关于Mac中Clion使用OpenCV

    关于Mac中Clion使用OpenCV 目标 Clion能够使用OpenCV 步骤 下载安装cmake,官网下载 下载OpenCV mac/linux版 使用cmake gui编译opencv安装包, ...

  8. Python学习笔记——基础篇【第五周】——random &amp&semi; time &amp&semi; datetime模块

    random模块 随机数 mport random print random.random() print random.randint(1,2) print random.randrange(1,1 ...

  9. Problem F&colon; 多少个最大值?

    Description 输入若干个int类型的整数,求它们的最大值及其个数. Input 输入 若干个int类型的整数,至文件尾为止. Output 输出只有一行:There are # maximu ...

  10. 如何在关闭ssh连接的情况下,让程序继续运行?

    [http://blog.csdn.net/smstong/article/details/5872309] 对Unix,Linux类服务器维护经常是通过ssh完成的,而有些操作比较费时,如更新程序等 ...