user1297102
user1297102

Reputation: 661

Make a class field read only after the fact

I'm working in a framework that forces me to create an instance of a class with the default constructor, so I unfortunately can't use 'readonly` and pass in an argument to the field.

Immediately after I create the instance, I plan to just set the field via a public property unless there's a more appropriate way.

Is it possible to force this field to be read only after its set? Without using a bool or some counter logic in the property's set?

update with some pseudocode

public class SomeClass
{
    public Create()
    {
        object = Framework.CreateClass<NeedArgument>();
        object.mustSet = value;
    }
}

public class NeedArgument : FrameworkBase
{
    public mustSet;
    public NeedArgument(){}
    public NeedArgument(value) { mustSet = value }

}

Upvotes: 2

Views: 465

Answers (4)

Pieter Geerkens
Pieter Geerkens

Reputation: 11883

Compose the field with two backing fields: one as normal, and the other being bool HasBeenSet = false;. Only allow a set if HasBeenSet is false, then set it after setting the value.

This can probably be generalized to a generic-type monad, but it is too late here to try writing sample code for that just now. The whole motivation of monads after all is to wrap additional information around an existing type. It would be the read-only monad (or perhaps the late-read-only monad.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500525

No, there's nothing to do that easily.

One option you might consider is using the builder pattern: make one mutable type, with a method which converts an instance of that mutable type into an instance of an immutable type... which can have readonly fields, of course. That may not work if the framework you're using requires the "eventual" type to be the one it started constructing, of course.

C#'s object initializer syntax makes this pretty pleasant. For example, in Noda Time you can write:

Period period = new PeriodBuilder { Days = 1, Hours = 22 }.Build();

If you can't change the type, then you need to implement some sort of "popsicle immutability" or "write-once immutability", both of which are fiddly and irritating.

Upvotes: 5

Vinay Pandey
Vinay Pandey

Reputation: 8913

Inherit the class into your class that has required construtors and assign value to it, property overriding is an option for you.

Upvotes: 1

Dennis
Dennis

Reputation: 37770

without using a bool or some counter logic in the property's set

No, it's impossible. You should add some initialization logic for field.

Upvotes: 1

Related Questions