You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:42:27