2009-11-19 69 views
0

我对创建一个不可修改属性的不可变类以及从其派生的可变类感兴趣。这些对象将是表示数据库记录的简单数据对象,因此它们只有属性的不可变值。任何方式来从C#中的不可变对象派生可变对象?

我的目标是通过基于数据库值设置属性,但将这些对象的只读版本传回应用程序,让我的数据访问层正常创建对象的可变版本。 (如果开发者真的想要,代码可以明确地将不可变对象转换回可变对象的事实,我很好)。

我可以这样做uglily(是一个单词吗?),使用方法getter和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); } 
} 

我宁愿尽可能使用自动性能 - 他们是在调试的时候好多了。除此之外,我并不关心代码的外观,因为它只是全部来自代码生成器,并且永远不会被查看。

任何想法?

回答

3

我会使用一个接口。拥有一个返回给客户端的只读接口和一个实现它的完全可写类,但仅用于数据访问层。

interface IReadOnlyObject 
{ 
    int Property { get; } 
} 

class DALObject : IReadOnlyObject 
{ 
    public int Property { get; set; } 
} 
+0

这很完美 - 我的思维如此枯燥,我甚至没有考虑过接口,但这对我的场景绝对有用。非常感谢你。 – 2009-11-19 22:06:06

2

你可以有你的数据层的回只读接口:

interface IClient 
{ 
    int getClientId(); 
} 

那么你不需要关心,如果你的具体实施有一个setter与否 - 来电者只会使用吸气剂。

作为一个侧面说明 - 你的代码看起来更象Java比C#,所以我居然会使用:

interface IClient 
{ 
    int ClientId { get; } 
} 
+0

完美 - 看起来你和马特回答几乎相同的时间... 我不喜欢在Java的语法,但在我的例子,我不得不让他们分开,如果我想只实现在吸气不变的版本 - 类似java的方式是我当时唯一可以考虑的方式。 接口将是完美的 - 谢谢。 – 2009-11-19 22:08:07

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. 
} 
+0

谢谢 - 我想“不可变的”不是描述我目标的正确词汇。我只想要一个开发人员无法轻易修改外部代码的对象。它不是真正的不变的,只是几乎不变的。 当然,从我所知道的情况来看,确实不存在真正不可改变的领域 - 一旦你对游戏进行了反思,修改私有只读字段是可能的。 – 2009-11-19 22:13:22

0

有一个基类,它不提供增变,但不提供不变性的承诺。有一个派生的不可变类和一个单独派生的可变类。所有类都应该有一个接受基类的构造函数,以及一个可重载/重载的“AsImmutable”属性,它将返回不可变派生类的对象,可以通过调用构造函数或(如果对象已经是不可变类)返回本身。