我有兴趣创建一个具有无法修改的属性的不可变类,以及一个从中派生的可变类。这些对象将是表示数据库记录的简单数据对象,因此它们只具有属性的不可变值。
我的目标是让我的数据访问层正常创建对象的可变版本,方法是根据数据库值设置属性,但将这些对象的只读版本传递回应用程序。 (我很好,如果开发人员真的想要,代码可以显式地将不可变对象强制转换为可变对象。)
我可以这样做(这是一个单词吗?),使用getter和setter的方法,并为可变类提供一个公共的新setter:
public class ImmutableClient {
private int _clientId;
public int getClientId() { return _clientId; }
protected void setClientId(int clientId) { _clientId = clientId; }
}
public class Client : ImmutableClient {
public new void setClientId(int clientId) { base.setClientId(clientId); }
}
如果可能的话,我更喜欢使用自动属性 - 它们在调试时更好。除此之外,我并不关心代码的外观,因为它只是来自代码生成器而且永远不会被看到。
有什么想法吗?
答案 0 :(得分:3)
我会使用一个界面。有一个只读的接口返回给客户端,一个完全可写的类实现它,但只用在数据访问层。
interface IReadOnlyObject
{
int Property { get; }
}
class DALObject : IReadOnlyObject
{
public int Property { get; set; }
}
答案 1 :(得分:2)
您可以让数据层返回只读界面:
interface IClient
{
int getClientId();
}
然后你不需要关心你的具体实现是否有一个setter - 你的调用者只会使用getter。
作为旁注 - 您的代码看起来更像Java而不是C#,所以我实际上会使用:
interface IClient
{
int ClientId { get; }
}
答案 2 :(得分:0)
不可变意味着不可改变。当我看到一个类型是不可变的时,我知道我可以缓存它并多次操作它而不会改变它。可变状态使得这种假设毫无价值。
class Foo
{
// I'm immutable
}
class Bar : Foo
{
// I add mutable properties
}
...
void F(Foo foo)
{
// foo is immutable - therefore Bar (mutable) *cannot* be derived from Foo.
}
答案 3 :(得分:0)
有一个基类,它不提供任何mutator但不提供不变性的承诺。有一个派生的不可变类和一个单独派生的可变类。所有类都应该有一个接受基类的构造函数,以及一个可重载/重载的“AsImmutable”属性,该属性将返回一个不可变派生类的对象,可以通过调用构造函数或(如果对象已经是不可变类)返回本身。