规则: 属性不应该返回数组
即使属性是只读的,该属性返回的数组也不是写保护的。 若要使数组不会被更改,属性必须返回数组的副本。
如下面的代码,就违背了这个规则:
public class Book
{
private string[] _Pages;
public Book(string[] pages)
{
_Pages = pages;
}
public string[] Pages
{
get { return _Pages; }
}
}
如何修复:
方法1,下面的示例通过将属性更改为方法来修复冲突。
public
class Book
{
private
string[] _Pages;
public Book(string[] pages)
{
_Pages = pages;
}
public
string[] GetPages()
{
// Need to return a clone of the array so that consumers
// of this library cannot change its contents
return (string[])_Pages.Clone();
}
}
方法2,将属性更改为返回一个 ReadOnlyCollection。
public
class Book
{
private ReadOnlyCollection<string> _Pages;
public Book(string[] pages)
{
_Pages = new ReadOnlyCollection<string>(pages);
}
public ReadOnlyCollection<string> Pages
{
get { return _Pages; }
}
}
方法3,将属性更改为返回一个 Collection 来修复冲突。
public
class Book
{
private Collection<string> _Pages;
public Book(string[] pages)
{
_Pages = new Collection<string>(pages);
}
public Collection<string> Pages
{
get { return _Pages; }
}
}
注意:Collection<T>有2个构造方法,public Collection();和public Collection(IList<T> list);第二种方法使用IList<T>初始化的Collection<T>是只读的。
所以方法3里的Pages是只读的,例如下面的代码都会捕获notsupportedexception:
Collection<string> t = new Collection<string>(new string[] { "a", "b" });
try
{
t[0] = "c";
}
catch (NotSupportedException ex) { }
Book b = new Book(new string[] { "a", "b" });
try
{
b.Pages[1] = "c";
}
catch (NotSupportedException ex) { }
try
{
b.Pages.RemoveAt(0);
}
catch (NotSupportedException ex) { }