请参阅以下代码:
public class Program
{
private static void Main()
{
var c = new MonthClass();
string[] months = (string[])c.GetMonths();
months[0] = "Thursday";
var d = c.GetMonths();
Console.WriteLine(d.First());
}
}
public class MonthClass
{
private readonly string[] _months =
{
"January", "February", "March", "April","May","June","July",
"August","September", "October", "November","December"
};
public IEnumerable<string> GetMonths() => _months;
}
Run Code Online (Sandbox Code Playgroud)
请注意,它MonthClass._months是私有且只读.但是,第二次调用GetMonths返回Thursday作为数组的第一个元素而不是January.
如何更改私有只读成员的值MonthClass以及如何防止这种情况?
在阅读答案并进行自己的研究之后.我相信以下内容将解决这个问题:
private readonly string[] _months =
{
"January", "February", "March", "April","May","June","July",
"August","September", "October", "November","December"
};
public IEnumerable<string> GetMonths
{
get { foreach (var month in _months) yield return month; }
}
Run Code Online (Sandbox Code Playgroud)
GetMonths()返回对数组的引用.任何具有返回值的人都有对数组的引用,并且可以更改它.
那么,如果您发生了对从该公共方法返回的数组的私有引用,该怎么办?public方法返回对该对象的引用.readonly适用于引用,而不适用于对象本身.
此代码功能相同:
public class C {
private readonly string[] _array = new [] { "foo" };
public string[] GetArray() => _array;
}
public class D {
public static void Test() {
C c = new C();
c.GetArray()[0] = "bar";
}
}
Run Code Online (Sandbox Code Playgroud)
以下是修复方法:
public ReadOnlyCollection<String> GetMonths() {
return Array.AsReadOnly(_months);
}
Run Code Online (Sandbox Code Playgroud)
这将返回一个不同的实际对象,一个实际上禁止写入的对象 - 而不仅仅是对同一个数组的不同类型的引用.
您也可以返回ReadOnlyCollection而不是IEnumerable,因为您返回的实际对象是可索引的.
如果要返回一个可变的对象,但不允许任何人更改私有_months字段,则可以:
public List<string> GetMonths() => _months.ToList();
Run Code Online (Sandbox Code Playgroud)
这样做:
var mutableMonths = c.GetMonths().ToList();
Run Code Online (Sandbox Code Playgroud)
我恳请你不要将属性命名为"Get",而不是从属性返回一个新对象.这是方法的合适案例.
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |