views:

159

answers:

3

I'm interested in making an immutable class that has properties that cannot be modified, and a mutable class that derives from it. These objects would be simple data objects representing database records, so they would have only immutable values for the properties.

My goal is to have my data access layer create the mutable versions of the objects normally, by setting the properties based on the database values, but passing readonly versions of these objects back to the application. (I'm ok with the fact that the code could explicitly cast the immutable object back into a mutable one if the developer really wanted to.)

I can do this uglily (is that a word?), using methods for getters and setters and having a public new setter for the mutable class:

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); }
}

I'd prefer to use auto-properties if possible - they're much nicer when debugging. Other than that, I don't really care how the code looks, since it's just going to all come from a code generator and never be looked at.

Any ideas?

+3  A: 

I would use an interface. Have a read only interface that is returned to the client and a fully writeable class that implements it but is only used in the data access layer.

interface IReadOnlyObject
{
    int Property { get; }
}

class DALObject : IReadOnlyObject
{
    public int Property { get; set; }
}
Matt Breckon
That's perfect - I had my mind so dead-set on classes that I didn't even think about interfaces, but that would absolutely work for my scenario. Thank you very much.
Joe Enos
+2  A: 

You can have your data layer return a read-only interface:

interface IClient
{
     int getClientId();
}

Then you don't need to care if your concrete implementation has a setter or not - your callers will only use the getter.

As a side note - your code looks more like Java than C#, so I would actually use:

interface IClient
{
     int ClientId { get; }
}
Groo
Perfect - looks like you and Matt answered almost the exact same time...I don't like the java-like syntax, but in my example, I had to keep them separate if I wanted to implement only the getter in the immutable version - the java-like way was the only way I could think of at the time.Interfaces will be perfect - thanks.
Joe Enos
A: 

Immutable means immutable. When I see that a type is immutable, I know that I can cache it and operate on it multiple times without it ever changing. Mutable state makes that assumption worthless.

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.
}
280Z28
Thanks - I guess "immutable" wasn't the right word for describing my goal. I just wanted an object that the developer couldn't easily modify in outside code. It isn't truly immutable, just practically immutable.Of course, from what I can tell, there really isn't such a thing as a truly immutable field - once you get reflection into the game, modifying private readonly fields is possible.
Joe Enos