基于Bogus生成带唯一AddressType的随机Person地址集合
解决Bogus生成唯一AddressType及动态获取枚举数量的问题
嘿,这个场景我之前做测试数据生成时刚好遇到过,给你两个核心解决方案,完美匹配你的需求:
一、保证每个Person的AddressType唯一
Bogus本身提供了便捷的方法来获取不重复的枚举值,同时我们也可以手动维护状态来控制唯一性,两种方式都可行:
方法1:利用Bogus自带的PickRandom唯一选择功能
Bogus的PickRandom方法有个重载,第二个参数传true就能返回不重复的元素,刚好适配我们的需求。在生成Person的Addresses时,先确定要生成的地址数量,再挑选对应数量的唯一AddressType,然后为每个类型生成地址:
// 先定义你的枚举、Address和Person类 public enum AddressType { work, home, SPAR } public class Address { public string StreetAddress { get; set; } public string ZipCode { get; set; } public string City { get; set; } public AddressType AddressType { get; set; } } public class Person { public string FirstName { get; set; } public string LastName { get; set; } public List<Address> Addresses { get; set; } = new List<Address>(); } // 配置Faker生成器 var addressFaker = new Faker<Address>() .RuleFor(a => a.StreetAddress, f => f.Address.StreetAddress()) .RuleFor(a => a.ZipCode, f => f.Address.ZipCode()) .RuleFor(a => a.City, f => f.Address.City()); var personFaker = new Faker<Person>() .RuleFor(p => p.FirstName, f => f.Name.FirstName()) .RuleFor(p => p.LastName, f => f.Name.LastName()) .RuleFor(p => p.Addresses, (f, p) => { // 这里动态获取枚举数量,替代硬编码的3 var addressTypeCount = Enum.GetValues<AddressType>().Length; // 随机生成0到枚举总数之间的地址数量(包含0和总数) var addressCount = f.Random.Int(0, addressTypeCount); if (addressCount == 0) return new List<Address>(); // 挑选指定数量的唯一AddressType var uniqueTypes = f.PickRandom<AddressType>(addressCount, true); // 为每个唯一类型生成对应的地址 return uniqueTypes.Select(type => addressFaker.Clone() .RuleFor(a => a.AddressType, _ => type) .Generate()) .ToList(); }); // 测试生成 var testPeople = personFaker.Generate(5);
方法2:手动维护HashSet跟踪已用类型
如果你需要更灵活的控制(比如后续要加一些自定义过滤逻辑),可以用HashSet来记录已经使用过的AddressType,确保不会重复:
.RuleFor(p => p.Addresses, (f, p) => { var addressTypeCount = Enum.GetValues<AddressType>().Length; var addressCount = f.Random.Int(0, addressTypeCount); var usedTypes = new HashSet<AddressType>(); var addresses = new List<Address>(); while (addresses.Count < addressCount) { var randomType = f.PickRandom<AddressType>(); // HashSet.Add返回true表示该类型未被使用过 if (usedTypes.Add(randomType)) { addresses.Add(addressFaker.Clone() .RuleFor(a => a.AddressType, _ => randomType) .Generate()); } } return addresses; });
二、动态获取AddressType枚举的数量
完全不需要硬编码3,用C#的枚举静态方法就能动态获取成员数量:
- 对于C# 7.3及以上版本,用
Enum.GetValues<AddressType>().Length,类型安全更简洁; - 如果是旧版本,用
Enum.GetValues(typeof(AddressType)).Length也可以。
这样以后你给AddressType新增枚举值时,代码完全不需要修改,会自动适配新的数量。
内容的提问来源于stack exchange,提问作者jZen
相关产品推荐
相关产品推荐

