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

如何在C#中限制Process类的Exams属性仅使用指定Exam实例?

解决方案

要实现"确保Process.Exams中的对象都属于预定义集合"的需求,需要从预定义集合的暴露、限制Exam实例的创建、添加验证逻辑三个方面入手,具体步骤如下:

1. 改造预定义Exam集合的静态类

首先完善PossibleExams,对外暴露所有可用实例、完整集合,以及根据ID查找实例的方法,方便外部获取和后续验证:

public static class PossibleExams
{
    // 公开单个预定义考试实例
    public static readonly Exam Exam1 = new Exam(1, "Exam 1");
    public static readonly Exam Exam2 = new Exam(2, "Exam 2");
    public static readonly Exam Exam3 = new Exam(3, "Exam 3");
    public static readonly Exam Exam4 = new Exam(4, "Exam 4");
    public static readonly Exam Exam5 = new Exam(5, "Exam 5");

    // 公开只读的完整可用考试集合,用于验证和遍历
    public static IReadOnlyList<Exam> AllExams { get; } = new List<Exam>
    {
        Exam1, Exam2, Exam3, Exam4, Exam5
    }.AsReadOnly();

    // 根据ID获取预定义实例,避免外部随意创建
    public static Exam GetById(int id)
    {
        return AllExams.FirstOrDefault(e => e.Id == id) 
            ?? throw new ArgumentException($"不存在ID为{id}的预定义考试", nameof(id));
    }
}

2. 限制Exam实例的创建

为了防止外部代码随意创建不属于预定义集合的Exam实例,将Exam的构造函数设为internal(如果和PossibleExams在同一个程序集),只有预定义类能创建实例:

public class Exam
{
    [Required]
    public int Id { get; }
    
    [Required]
    public string Name { get; } // 建议去掉?,因为构造时会校验非空

    // 设为internal,仅同程序集的PossibleExams可调用
    internal Exam(int id, string name) 
    {
        Id = id;
        Name = name ?? throw new ArgumentNullException(nameof(name), "考试名称不能为空");
    }
}

3. 添加自定义验证确保合规

创建自定义验证属性,校验Process的Exams集合中所有实例都属于预定义集合:

public class ValidExamCollectionAttribute : ValidationAttribute
{
    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        var exams = value as List<Exam>;
        if (exams == null)
        {
            return new ValidationResult("考试集合不能为空");
        }

        foreach (var exam in exams)
        {
            if (!PossibleExams.AllExams.Contains(exam))
            {
                return new ValidationResult($"ID为{exam.Id}的考试不属于预定义集合");
            }
        }

        return ValidationResult.Success;
    }
}

然后在Process类的Exams属性上添加该验证属性:

public class Process
{
    public int Id { get; set; }

    [Required]
    public Person? Person { get; set; }

    [Required]
    [MinLength(1, ErrorMessage = "至少选择一项考试")]
    [ValidExamCollection] // 新增自定义验证
    public List<Exam>? Exams { get; set; }

    [Required]
    [DataType(DataType.Date)]
    public DateTime ProcessDate { get; set; }
}

使用示例

后续创建Process实例时,直接从PossibleExams获取Exam实例即可确保合规:

var validProcess = new Process
{
    Person = new Person(), // 假设Person类已定义
    Exams = new List<Exam>
    {
        PossibleExams.Exam1,
        PossibleExams.Exam3
    },
    ProcessDate = DateTime.Today
};

内容的提问来源于stack exchange,提问作者Frixer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 15:58:17