[英]“Read only” Property Accessor in C#
我有以下 class:
class SampleClass
{
private ArrayList mMyList;
SampleClass()
{
// Initialize mMyList
}
public ArrayList MyList
{
get { return mMyList;}
}
}
我希望用户能够获得 mMyList,这就是为什么我通过属性公开“get”但是我不希望他们对 object(即 MyList.Add(new Class());) 进行更改以使其回到我的 class。
我想我可以返回 object 的副本,但这可能会很慢,我正在寻找一种方法来提供编译时错误,通知用户他们不应该期望能够从财产。
这可能吗?
使用 ArrayList,您将受到相当的限制,因为 BCL 中没有只读的非泛型集合 class。 快速而肮脏的解决方案是返回一种 IEnumerable。
public IEnumerable MyList
{
get { return mMyList;}
}
这实际上不会阻止某人投射到 ArrayList 但默认情况下也不允许编辑
您可以通过调用 ArrayList.ReadOnly 返回一个有效的只读列表。 然而,它的返回类型是 ArrayList,因此用户仍然可以使用.Add 进行编译,但会产生运行时错误。
使用ArrayList.ReadOnly()方法构造并返回列表周围的只读包装器。 它不会复制列表,而只是在其周围创建一个只读包装器。 为了获得编译时检查,您可能希望按照@Jared 的建议将只读包装器作为 IEnumerable 返回。
public IEnumerable MyList
{
get { return ArrayList.ReadOnly(mMyList); }
}
只读集合只是一个带有防止修改集合的包装器的集合。 如果对基础集合进行了更改,则只读集合会反映这些更改。
此方法是 O(1) 操作。
只是为了扩展 JaredPar 的答案。 正如他所说,返回实际的支持字段并不完全安全,因为用户仍然能够将IEnumerable
动态转换回ArrayList
。
我会写这样的东西来确保不对原始列表进行任何修改:
public IEnumerable MyList
{
get
{
foreach (object o in mMyList)
yield return o;
}
}
再说一次,我可能还会使用通用列表( IEnumerable<T>
)来保证类型安全。
使用ReadOnlyCollection
。
return new ReadOnlyCollection<object>(mMyList)
。
您还可以将ReadOnlyCollection
字段,它将自动反映基础列表中的更改。 这是最有效的解决方案。
如果您知道 mMyList 仅包含一种类型的 object(例如,它只有 DateTimes),您可以返回ReadOnlyCollection<DateTime>
(或其他类型)以获得额外的类型安全。 如果您使用的是 C# 3,您可以简单地编写
return new ReadOnlyCollection<DateTime>(mMyList.OfType<DateTime>().ToArray())
但是,这不会自动更新底层列表,效率也较低(它将复制整个列表)。 最好的选择是使 mMyList 成为通用List<T>
(例如, List<DateTime>
)
您应该将返回值包装在只读集合中。
可从 .NET v2.0 获得
public ArrayList MyList { get; private set; }
只需将属性设为 Sealed(或 VB.NET 中的 NotInheritable)并且只读,如下所示:
public sealed readonly ArrayList MyList
{
get { return mMyList;}
}
也不要忘记将支持字段设为只读:
private readonly ArrayList mMyList;
但为了初始化 mMyList 的值,您必须仅在构造函数中对其进行初始化,如下例所示:
public SampleClass()
{
// Initialize mMyList
mMyList = new ArrayList();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.