我设计了一个类似于CD的类,我还有另一个类来测试我设计的类。 测试类创建一个CD的新对象,并用变量等填充它。
我的问题是测试类说我的类因为在创建对象后变量数组发生变化而失败,并且这些变量没有直接改变实际的Class属性,我该如何阻止它?
测试类:
string[] myCdTracks = { "Song 1", "Song 2", "Song 3" };
string[] myCdTracks2 = { "Song 1", "Song 2", "Song 3" };
CD myCd = new CD("My Songs", "Fergus", "Rock", myCdTracks);
for (int i = 0; i < myCdTracks.Length; i++)
{
它不应该在这里改变它的值。
myCdTracks[i] = "aaaa";
}
result = "PASS";
if (myCd.Tracks.Length != testArray.Length)
{
result = "FAIL";
}
else
{
for (int i = 0; i < myCd.Tracks.Length; i++)
{
if (myCd.Tracks[i] != testArray[i])
{
result = "FAIL";
}
}
}
我的CD课程:
public class CD
{
string _Name;
string _Artist;
string _Genre;
string[] _Tracks;
public CD(string name, string artist, string genre, string[] tracks)
{
_Name = name;
_Artist = artist;
_Genre = genre;
_Tracks = tracks;
}
// ... Some properties
public string[] Tracks
{
get
{
return _Tracks;
}
set
{
for (int i = 0; i < _Tracks.Length; i++)
{
_Tracks[i]= value[i];
}
}
}
}
答案 0 :(得分:3)
我的问题是测试类说我的类因为在创建对象后变量数组发生变化而失败,并且这些变量没有直接改变实际的Class属性,我该如何阻止它?
问题是您刚刚将引用复制到构造函数中的轨道名称数组中。这意味着通过您的引用仍然可以看到从外部对阵列的任何更改。一个简单的选择是克隆数组:
_Tracks = (String[]) tracks.Clone();
...甚至更改变量类型并创建只读集合:
_Tracks = new ReadOnlyCollection<string>(tracks);
幸运的是,您不需要担心字符串对象本身的内容会发生变化,因为字符串是不可变的。 非常重要,因为您了解当前表单中的程序正在发生什么 - 而我的article on reference types vs value types可能有所帮助。
答案 1 :(得分:1)
另请注意,在Tracks
属性的属性设置器中,如果要设置的数组包含的元素多于当前_Tracks
数组,则很可能会遇到麻烦。
我建议在构造函数和属性setter中使用Jon Skeet的变体。