根据测试用例定义class

Define class based on test case

谁能告诉我如何定义 class 学生,使最后一个测试用例得到满足。 我无法理解最后一个函数 GetId() 的方法实现。

public const int basicId = 12345;
public const int studentId = 88888;
public const string sampleName = "User Name";
[TestMethod] 
public void StudentIsInitializedCorrectly()
{
      User student = new Student(sampleName, basicId, studentId);
      Assert.AreEqual(sampleName, student.GetName());
      Assert.AreEqual(basicId, student.GetId());
      Assert.AreEqual(studentId, ((Student)student).GetId());
}

谢谢

我从评论中得知您正在完成一些测试驱动开发 (TDD) 练习,并且您在理解此示例时遇到困难。考虑到这一点,我是这样看的:

  1. 测试中发生的第一件事是,当您创建 Student 的实例时,它被分配给类型为 User 的变量。这个 可以 有不同的工作方式,但最明显的解释是 User 是基础 class,并且 Student 继承 User.
  2. 接下来的两个语句直接调用 student 变量上的方法。因为这个变量的类型是User,那些方法一定存在于Userclass中。同样,这有多种实际可行的方法,但最简单的是假设这些方法需要 return 的值实际上存储在 User class.

这两点将我们引向 User class,看起来像这样:

class User
{
    private readonly string _name;
    private readonly int _id;

    public User(string name, int id)
    {
        _name = name;
        _id = id;
    }

    public string GetName() { return _name; }
    public int GetId() { return _id; }
}

上面确保当我们通过类型为 User 的变量查看对象实例时,我们仍然可以调用 GetName()GetId() 方法,并取回我们期望的值。

现在我们来到方法中的第三个也是最后一个测试。请注意,此测试在调用方法之前将 student 变量转换为 class Student。另请注意,此方法预期 return studentId 中的值并且 而不是 basicId 中的值,这是基础 class 的 GetId() 方法应该是 return.

所以我们有相同的方法名称,用于相同的对象实例,但根据对象的 编译时 类型(又名 "static type").这与 运行-time 类型相反,后者是对象的实际类型。

鉴于此,我们必须在Studentclass中声明一个新的GetId()方法,当然还要提供一种方法让它return不同的ID对象初始化期间使用的值:

class Student : User
{
    private readonly int _id;

    public Student(string name, int basicId, int studentId)
        : base(name, basicId)
    {
        _id = studentId;
    }

    public new int GetId() { return _id; }
}

唯一的问题是,鉴于我们已经知道 User class 有一个名称完全相同的方法,您将用您的方法隐藏 class 的方法新 GetId() 方法。因此,需要 new 关键字来避免任何编译时警告。

我个人的偏好是避免方法隐藏总是。它几乎总是错误的设计选择,只有在某些外部需求强制使用它时才应使用它。

(注意上面classes中的字段被标记为readonly。测试中没有任何内容要求如此,但测试中也没有任何内容阻止它. 我的偏好是使字段 readonly 除非它们不能,因此在这里使用 readonly).