views:

237

answers:

6

Automatic properties let me replace this code:

private MyType myProperty;
public MyType MyProperty
{
    get { return myPropertyField; }
}

with this code:

public MyType MyProperty { get; private set; }

with a few changes here and there - but is there a way to replace this code:

private readonly MyType myProperty;
public MyType MyProperty
{
    get { return myPropertyField; }
}

with something similar?

+1  A: 

readonly can only be applied to fields, so I believe not.

Could you not just use:

public readonly MyType MyProperty;

as it is then only assignable from the constructor anyway?

JDunkerley
The "good design" gurus will kill you for this, but I give you +1 because it actually works and never seems to cause any problems in practice, and also for compensation for future downvotes.
erikkallen
See my response to Jan Bannister... there are plenty of reasons not to use public fields, even readonly ones.
Jon Skeet
+5  A: 

No, but this idea is being tracked on Connect.

Mark Seemann
+1  A: 

No, there's no way you can do it. In fact, I don't see why would you want to get a value of a property which has not been set previously. For obvious reasons, you cannot set the value if there's neither set accessor, nor backing field.

Anton Gogolev
You'd have to be able to set it - but only from the constructor, as per any normal readonly field.
Jon Skeet
A: 

That's really convoluted mate.

Just make it a public readonly field.

Jan Bannister
At which point you lose all the benefits of properties - including source and binary compatibility when you eventually want to write a more fully-fledged property implementation. Public instance fields are a bad idea IMO.
Jon Skeet
I would normally agree that you should never use public fields. But this a weird use case. It's read only, it's not meant to be written to.
Jan Bannister
BTW I really liked your book 'C# in Depth' Very good read!
Jan Bannister
@Jan: Imagine if you compile your `readonly` field, then later it is replaced by a property with only a public get accessor (which could still return the value of a `private readonly` field.) This will break binary compatability.
Blixt
@Jan: Just because it's read only doesn't mean you might not want to put extra logic in there eventually. Likewise, the philosophical objection to exposing fields (they're an implementation detail, unlike properties which are part of the API) doesn't go away just because it's read only. Glad you liked the book though :)
Jon Skeet
You missed another advantage of properties over fields: properties can be members of interfaces but fields cannot.
finnw
@Blixt, @Tony the PonyOK OK OK. These are all lovely comments but they all address possible future changes and not the actual question. So you are over engineering your answers. Which is common, don't worry about it.
Jan Bannister
+4  A: 

No, unfortunately not. I would very much like the feature, which could look like this:

public readonly string Name { get; }

or (slightly oddly)

public readonly string Name { get; readonly set; }

This would be converted into something like:

private readonly string <>_Name;

public string Name { get { return <>_Name; } }

The twist is that setter calls would be allowed - but only within the constructor. Such calls would be converted directly into assignments to the backing field.

I would dearly, dearly love such a feature. Maybe for C# 5...

Jon Skeet
I prefer your first example, but should not the `set` keyword be specified too, even if a property always has a setter? Especially since the setter can have different access levels even if it is `readonly` (right? I'm thinking of `private` and `protected`.)
Blixt
"...even if a property always..." -- to clarify, I mean auto-properties, not "normal" properties.
Blixt
@Blixt: Possibly. I guess the implication is "it's an auto-property, so there must be some way to set it..." I suspect that any combination is going to be awkward somewhere :)
Jon Skeet
I suppose. But what if you change the `private` in your third code block to `protected`? What should the short-hand code be to produce that output?
Blixt
@Blixt: You shouldn't be able to do that, IMO. Automatic properties *always* have private backing fields... and I wouldn't want readonly ones to be able to be set from derived constructors anyway.
Jon Skeet
True, but I would say that is because there is no reason whatsoever to have the backing field accessible. For `readonly` the situation is different, since the backing field *must* be accessed directly by your code (once compiled.) And since it *is* possible to have a `protected` field, you might be preventing some kind of case where `protected readonly` makes sense by only supporting `private`. I wouldn't use `protected` either, but I've seen cases where limiting functionality based on these kinds of assumptions have prevented some neat functionality (such as `where T : Enum`.)
Blixt
Well you could make the *getter* accessible to derived classes - and if you're already thinking that the derived class may want to be able to set the value of the field, what's to stop you from making a protected constructor which takes the value to set? I guess I don't feel too strongly on this either way, but the main thing is to get this feature into the language in the first place :)
Jon Skeet
I see your point and I'm not really that sensitive about it either =) But my point is just that one should avoid disallowing functionality that is practically there unless you have a very good reason to do so.
Blixt
I've seen people asking elsewhere for support for methods that can only be called from the constructor, but which can modify readonly variables. Perhaps the setter could be that sort of feature. I'm not sure what you'd call them in C# - the managed C++ 'initonly' keyword is actually more descriptive than C#'s 'readonly' keyword.
Simon
@Simon: I haven't heard of that feature request before, but it makes a lot of sense.
Jon Skeet
+6  A: 

Indeed, there is no way to do this at present.

We realize that in C# 3 we produced a bit of a philosophical oxymoron. The design of LINQ is heavily steeped in traditional immutable functional style of programming -- execution is deferred, queries are represented by immutable monads, expression trees are immutable, and so on.

And yet at the same time object initializers, collection initializers and auto props all encourage a traditional mutable-component-based style of programming. It seems like we are pushing in both directions -- which is indicative of the nature of C#; it's a pragmatic programming language that supports many different styles of programming.

However, since we are all big fans of the immutable style of programming, and since we believe that this style will pay dividends in making it easier to ensure the correctness of massively multithreaded applications in future ubiquitous multi-core architectures, we're definitely interested in figuring out some way to tame the mutability we've introduced. Readonly autoprops are one obvious way to do that; a small step, but a good one.

That all said, we have not even shipped C# 4 yet, and have not announced that there will be any new language features after that. You should treat all my musings about hypothetical features of unannounced products as "for entertainment purposes only" speculations, not as promises or announcements.

Eric Lippert