返回正确的对象
本文关键字:对象 返回 | 更新日期: 2023-09-27 18:26:15
我试图完成一个编程练习,但有一个测试失败了。我做错了什么?
任务是:
编写一个管理机器人工厂设置的程序。
当机器人从工厂的地板上下来时,他们没有名字。
第一次启动它们时,会生成一个随机名称,例如RX837或BC811。
每隔一段时间,我们就需要将机器人重置到工厂设置,这意味着它们的名称将被删除。下次你问,它有了一个新名字。
程序的测试如下所示,失败的是Different_robots_have_Different_names:
public class RobotNameTest
{
private Robot robot;
[SetUp]
public void Setup()
{
robot = new Robot();
}
[Test]
public void Robot_has_a_name()
{
StringAssert.IsMatch(@"[A-Z]{2}'d{3}", robot.Name);
}
[Test]
public void Name_is_the_same_each_time()
{
Assert.That(robot.Name, Is.EqualTo(robot.Name));
}
[Test]
public void Different_robots_have_different_names()
{
var robot2 = new Robot();
Assert.That(robot.Name, Is.Not.EqualTo(robot2.Name));
}
[Test]
public void Can_reset_the_name()
{
var originalName = robot.Name;
robot.Reset();
Assert.That(robot.Name, Is.Not.EqualTo(originalName));
}
}
我的代码如下:
public class Robot
{
private List<string> Names = new List<string>();
private string name { get; set; }
public string Name { get { return this.name; } }
public Robot()
{
CreateName();
}
private void CreateName()
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var random = new Random();
StringBuilder sb = new StringBuilder();
sb.Append(
new string(
Enumerable.Repeat(chars, 3)
.Select(x => x[random.Next(x.Length)]).ToArray()
)
);
sb.Append(random.Next(100, 999));
if(Names.Any(word => word.Equals(sb.ToString())))
{
CreateName();
}
else
{
name = sb.ToString();
Names.Add(sb.ToString());
}
}
public void Reset()
{
this.name = "";
}
}
使Names
静态通过所有测试:
private static List<string> Names = new List<string>();
Static关键字表示在类级别上创建成员,而不是对象。
在您的情况下,所有机器人都将共享一个链接到单个名称列表。删除static关键字将导致Names
列表被创建为每个Robot对象。如果您想跟踪Robot构造函数被调用的次数,您可能应该有一个共享的名称列表,该列表在所有Robot对象之间共享。
测试失败是因为创建第二个对象时,它有一个新的空名称列表,而第一个Robot类对此一无所知。所以在您的情况下,Names.Any(...)
总是返回false。
要阅读更多详细信息,请考虑上面的msdn链接。
错误并不明显。Random
类使用从当前系统时间创建的随机种子进行初始化。与CPU时钟频率相比,产生系统时间的手表滴答声较慢。因此,如果new Random()
被调用两次fast,则random
很可能用相同的种子被初始化两次。
解决方案:将random声明为静态,并只初始化一次。
public class Robot
{
private static Random random = new Random();
...
}
现在,无论您创建了多少个机器人,random
都只创建一次。