枚举(Enum)是一个有个性的自定义类型 ,首先它定义出来的类型是值类型,Enum定义出来的类型就是穷举一个属性的所有可取值范围,比如户口本上的性别:男,女,听说泰国也是这样的,如果你的系统中需要,那就加个其(人)他(妖)也是可以的。枚举的作用,就是规范编程时的属性数据取值范围,不至于字符串拼错;另一方面,在数据库中,一般存男女时,都会用短整型或bit类型0,1来代替男女含义。其实在一些业务系统中的数据库中,有很多类型,就是这样设计的,用一组整型来分别代表不同的类别。
接下来看一下C#中定义枚举,一个普通枚举(Sex),一个位枚举或叫标记枚举(UserType):
/// <summary>
/// 性别枚举
/// </summary>
public enum Sex
{
/// <summary>
/// 其他
/// </summary>
None = 0,
/// <summary>
/// 男
/// </summary>
Male = 1,
/// <summary>
/// 女
/// </summary>
Female = 2,
}
/// <summary>
/// 用户枚举,位枚举
/// </summary>
[Flags]
public enum UserType
{
/// <summary>
/// app用户
/// </summary>
App = 1,
/// <summary>
/// web用户
/// </summary>
Web = 2,
/// <summary>
/// 小程序用户
/// </summary>
MiniPro = 4,
/// <summary>
/// 公众号用户
/// </summary>
OfficialAccounts = 8
}
Sex和UserType都是一种枚举属性,应该出现在一个实体类中:
/// <summary>
/// 人员类型
/// </summary>
public class Person
{
public int ID { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 性别
/// </summary>
public Sex Sex { get; set; }
/// <summary>
/// 用户类型
/// </summary>
public UserType UserType { get; set; }
}
对应数据库(mysql):
CREATE TABLE persons
(id
int NOT NULL AUTO_INCREMENT,name
varchar(45) DEFAULT NULL,sex
int DEFAULT NULL,usertype
int DEFAULT NULL,
PRIMARY KEY (id
)
)
上业务代码:
while (true)
{
Console.WriteLine("选择操作:1、添加 2、查询 3、枚举返回集合");
switch (Console.ReadLine())
{
case "1":
//模拟api json post,自动把Sex,UserType整数转成实体类中的枚举类型
var newPerson = System.Text.Json.JsonSerializer.Deserialize<Person>(@"{""Name"":""桂素伟"",""Sex"":1,""UserType"":15}");
AddPerson(newPerson);
break;
case "2":
foreach (var person in GetPersons())
{
Console.WriteLine("程序中看到的数据");
Console.WriteLine($"Name:{person.Name},Sex:{person.Sex},UserType:{person.UserType}");
Console.WriteLine("给用户返回Json");
//模拟从数据库查出数据转发成json到前端
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(person));
}
break;
case "3":
Console.WriteLine("Sex集合:");
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(GetEnumList<Sex>()));
Console.WriteLine("UserType集合:");
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(GetEnumList<UserType>()));
break;
}
}
}
static void AddPerson(Person person)
{
using (var con = new MySqlConnection("server=localhost;database=marsdb;uid=root;pwd=mars2020;"))
{
var sql = @"INSERT INTO `marsdb`.`persons`(`id`,`name`,`sex`,`usertype`) VALUES(@id,@name,@sex,@usertype);";
con.Execute(sql, person);
}
}
static List<Person> GetPersons()
{
using (var con = new MySqlConnection("server=localhost;database=marsdb;uid=root;pwd=mars2020;"))
{
var sql = @"select * from `marsdb`.`persons`";
return con.Query<Person>(sql).ToList();
}
}
static List<dynamic> GetEnumList<T>() where T : struct, Enum
{
var enums = Enum.GetValues<T>();
var list = new List<dynamic>();
foreach (var item in enums)
{
list.Add(new { Name = item.ToString(), Value = Convert.ToInt32(item) });
}
return list;
}
三个方法分别模拟了查询——返回JSON,添加——提交JSON,获取枚举名称和值——返回枚举键值集合JSON。
这里利用枚举,可以很优雅地实现“开发语义明确化,存传数据简约化”,人机友好。