views:

86

answers:

3

We have several domain objects which need to support both read-only and read-write modes; they currently have a bool Locked property for this--when Locked attempts to alter properties on the object result in an InvalidOperationException. The default state for the objects is Locked.

The object-initialization syntax of C# 3 introduces a small issue with these, in that the object must be unlocked (or default to be unlocked) during initialization and then locked explicityly at the end.

When using C# 3's object initialization syntax is there a means of receiving notification that the object is being intitialized or that initialization is complete? System.ComponentModel.ISupportInitialize was my best hope, but it doesn't get called.

+3  A: 

No, there is no such notification mechanism. The object initializer feature will simply call the specified constructor and then set the accessible fields / properties in the order they are listed. There is no interface available which supports notifications for this feature.

JaredPar
+2  A: 

No. The object initializers just are a compiler feature to assist in initializing your objects. They call the properties directly.

You need to either force constructor usage, or add a "lock" method to lock them down explicitly.

Reed Copsey
+3  A: 

You could use a fluent API and append it:

var obj = new MyType { Id = 123, Name = "abc"}.Freeze();

where the Freeze method returns the same instance (fluent) - something like:

class MyType {
    private bool isFrozen;
    public MyType Freeze() {
        isFrozen = true;
        return this;
    }
    protected void ThrowIfFrozen() {
        if (isFrozen) throw new InvalidOperationException("Too cold");
    }
    private int id;
    public int Id {
        get { return id; }
        set { ThrowIfFrozen(); id = value; }
    }
    private string name;
    public string Name {
        get { return name; }
        set { ThrowIfFrozen(); name = value; }
    }
}

(you could centralize the check a bit more if needed)

Marc Gravell
It's not what I was hoping for--but is solves the problem that I would otherwise have to be careful of the order of setting the properties (assuming isFrozen is exposed by property).var obj = new DomObj() { Frozen = true, Id = 5 }; // throws an exception since Frozen was set before Id.
STW
It also avoids the pain of having a settable property that appears to unfreeze(/thaw) the object - so I prefer a method like `Freeze()` rather than a property.
Marc Gravell