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

如何实现Person类的Teacher、Student两个属性仅可赋值其中一个?

你要的需求可以通过角色接口的方式实现,既满足直接创建Person对象的要求,也能保证每个Person只能对应教师/学生其中一个身份,完全符合你期望的实例化写法,具体实现如下:

1. 定义身份公共接口

首先定义一个空的身份标记接口,让Teacher和Student都实现该接口,作为Person类中身份属性的统一类型:

// 身份标记接口
public interface IPersonRole { }

2. 实现教师、学生类

两个类分别实现IPersonRole接口,保留各自的专属属性:

public class Teacher : IPersonRole
{
    // 教师专属属性
    public string TeacherId { get; set; }
    public DateTime HireDate { get; set; }
    public string Subject { get; set; }
}

public class Student : IPersonRole
{
    // 学生专属属性
    public string StudentId { get; set; }
    public string ClassName { get; set; }
    public double AverageScore { get; set; }
}

3. 改造Person类

在Person类中用IPersonRole类型存储身份,构造函数强制传入身份实例,从根源上保证每个Person有且仅有一个合法身份:

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }
    // 身份属性,对外只读禁止随意修改
    public IPersonRole Role { get; private set; }

    public Person(int id, string firstName, string lastName, string phoneNumber, IPersonRole role)
    {
        Id = id;
        FirstName = firstName;
        LastName = lastName;
        PhoneNumber = phoneNumber;
        // 校验身份合法性
        if (role == null) throw new ArgumentNullException(nameof(role));
        if (role is not Teacher && role is not Student) 
            throw new ArgumentException("身份只能为教师或学生", nameof(role));
        Role = role;
    }

    // 辅助属性,快速判断身份类型
    public bool IsTeacher => Role is Teacher;
    public bool IsStudent => Role is Student;

    // 辅助方法,安全转换身份类型,避免强制转换报错
    public Teacher GetTeacher() => Role as Teacher;
    public Student GetStudent() => Role as Student;
}

4. 按你期望的方式实例化

完全符合你要的调用写法:

// 实例化教师身份的Person
Person teacherPerson = new Person(1, "Hans", "Klok", "0636257135", new Teacher
{
    TeacherId = "T001",
    HireDate = new DateTime(2020, 9, 1),
    Subject = "物理"
});

// 实例化学生身份的Person
Person studentPerson = new Person(2, "Hans", "Klok", "0636257135", new Student
{
    StudentId = "S2024003",
    ClassName = "高一2班",
    AverageScore = 91.5
});

5. 使用示例

调用时可以快速判断身份并获取专属属性:

if (teacherPerson.IsTeacher)
{
    var teacher = teacherPerson.GetTeacher();
    Console.WriteLine($"教师授课科目:{teacher.Subject}");
}

if (studentPerson.IsStudent)
{
    var student = studentPerson.GetStudent();
    Console.WriteLine($"学生平均成绩:{student.AverageScore}");
}

这个方案比你最初设想的同时定义Teacher和Student两个属性的写法更严谨,完全避免了两个属性同时赋值、或者都为空的非法情况,也满足所有业务要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:48:04