我发誓我见过这样的例子,但已经用谷歌搜索了一段时间,找不到它。
我有一个类引用了一个对象并且需要一个 GET;方法。我的问题是我不希望任何人能够摆弄它,即我希望他们获得它的只读版本,(注意我需要能够在我的班级中更改它)。
谢谢
我发誓我见过这样的例子,但已经用谷歌搜索了一段时间,找不到它。
我有一个类引用了一个对象并且需要一个 GET;方法。我的问题是我不希望任何人能够摆弄它,即我希望他们获得它的只读版本,(注意我需要能够在我的班级中更改它)。
谢谢
不,没有办法做到这一点。例如,如果您返回 a List<string>
(并且它不是不可变的),那么调用者将能够添加条目。
解决这个问题的正常方法是返回一个不可变的包装器,例如ReadOnlyCollection<T>
.
对于其他可变类型,您可能需要在返回值之前对其进行克隆。
请注意,仅返回一个不可变的接口视图(例如,返回IEnumerable<T>
而不是List<T>
)不会阻止调用者转换回可变类型并进行变异。
编辑:请注意,除此之外,这种担忧是不可变类型更容易推理代码的原因之一:)
返回对精简接口的引用:
interface IFoo
string Bar { get; }
class ClassWithGet
public IFoo GetFoo(...);
如果对象不是太复杂/广泛,那么在它周围写一个包装器。
例如:
class A {
public string strField = 'string';
public int intField = 10;
}
class AWrapper {
private A _aObj;
public AWrapper(A aobj) {
_aObj = A;
}
public string strField {
get {
return _aObj.strField;
}
}
public int intField {
get {
return _aObj.intField;
}
}
}
所以现在你要做的就是给你的客户代码一个 AWrapper 类的实例,这样他们就可以只使用你允许他们看到的东西。
如果您的基类不是一成不变的,这可能会变得有点复杂并且可能无法很好地扩展,但对于大多数简单的情况它可能只是解决问题。我认为这被称为外观模式(但不要引用我的话=))
这是不可能的。获取和设置引用类型的访问器获取和设置对对象的引用。您可以通过使用私有(或内部)setter 来阻止对引用的更改,但如果对象被 getter 公开,则无法阻止对对象本身的更改。
您的问题看起来像您正在寻找:
public PropertyName { get; private set; }
但是,鉴于到目前为止的答案,我不确定我是否正确解释了您的问题。此外,我有什么资格去质问 Jon Skeet?:)
我同意 ReadOnlyCollection
看我的简单代码:
private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices
{
get
{
return (_devices.AsReadOnly());
}
}
ReadOnlyCollection 没有 Add 方法,因此用户无法向其添加属性。但不能保证用户是否可以通过调用对象的方法来修改对象......
我以某种方式面对过这个问题。我有一个 CategoryViewModel 类,它有一个我想要私有只读的属性 Category :
public CategoryViewModel
{
private Category { get; }
}
事实上,我希望它以只读方式导出到其他类。但是我不能做这样的事情。就我而言(也许它会帮助其他一些人),我想将它添加到存储库中。我发现的唯一方法是使用存储库作为参数 1 的函数,以及作为参数 2 的操作:
public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
action(repo, Category);
}
像那样,从其他地方,我可以做这样的事情:
categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));
这可以帮助其他人仅在某些情况下公开那里的财产并可以管理它们。