Is it possible to have a property that has a public getter but a non-public
setter? If so, how?
Something like this: (obviously this doesn't compile)
public string Data
{
get { return this._data; }
}
private string Data
{
set { this._data = value; }
}
Thanks
Brian W
--
Michael Culley
"Brian W" <brianw@gold_death_2_spam_rush.com> wrote in message
news:#fWTF4yxCHA.2296@TK2MSFTNGP10...
--
Greg Ewing [MVP]
http://www.claritycon.com/
"Brian W" <brianw@gold_death_2_spam_rush.com> wrote in message
news:#fWTF4yxCHA.2296@TK2MSFTNGP10...
No, and a number of people (myself included) think this is a pity. One
nice thing that would be possible if you could do this would be to have
a convention of *only* using the property, so that the only place where
the variable itself would be used would be the property itself. Further
syntax might then be introduced to reduce the visibility of the variable
to just the property, eg:
string Data
{
string data;
public get { return data; }
private set { data = value; }
}
--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet/
If replying to the group, please do not mail me too
First, I would prefer a syntax where you didn't have to specify the getters
and setters for this sort of case. e.g. a "property" keyword:
property string Data; // This would produce equivalent IL to Jon Skeet's
example above.
Second, I don't see much value in doing this. Fields and properties should
look much the same to the outside world-- unfortunately they don't quite--
but if they did, you might as well replace the Data property with a string
Data field. Then if you have to change it to be a property later than so be
it, but that change would ipso facto be because you didn't want the field
encapsulation.
The objections I can see to using a public field as opposed to a property
are:
a) Fields don't appear in the property browser
b) They appear different with reflection.
c) You might want additional "state" on your property that was hidden
outside the property (e.g. a "bool needsRecalculation" field).
Personally I think there should be less distinction between fields and
properties. There should, for example, be a common base class for
PropertyInfo and FieldInfo called e.g. DataMemberInfo with virtual methods
such as GetValue(), SetValue(). If you use reflection a lot, it is often a
pain to have to write parallel code to deal with fields and properties when
they have a lot of common behaviour from an "outside world" point of view. I
also don't see much reason (above nomenclature) why public fields shouldn't
be put in the "property browser". If the language designers are saying
"never have public fields" then they shouldn't allowed them in the language.
(I'm pretty sure some languages which disallow public fields but I can't
think of examples right now.) If they are not saying this, then my
deliberate choice to make a field public should be honored by at design
time.
I could certainly live with that.
> Second, I don't see much value in doing this. Fields and properties should
> look much the same to the outside world-- unfortunately they don't quite--
> but if they did, you might as well replace the Data property with a string
> Data field. Then if you have to change it to be a property later than so be
> it, but that change would ipso facto be because you didn't want the field
> encapsulation.
Ah, but you wouldn't, because convention would never let you have a Data
field, only a data field. At least, Microsoft's conventions wouldn't. I
think those conventions are important - it's worth knowing what you're
doing, in the same way that I avoid operator overloading. Knowing that
you're quite possibly calling code rather than just getting/setting has
different implications.
> The objections I can see to using a public field as opposed to a property
> are:
> a) Fields don't appear in the property browser
> b) They appear different with reflection.
> c) You might want additional "state" on your property that was hidden
> outside the property (e.g. a "bool needsRecalculation" field).
Also:
o Fields don't have separate access for reading and writing.
o Fields don't allow you to easily change the way a value is calculated;
it may be just backed now by a field, but later it could be a database
lookup, for instance. This is really just a stronger case of c)
admittedly, but worth mentioning, I believe. Similarly setting a
property could validate it. There may well be threading issues as well,
of course.
> Personally I think there should be less distinction between fields and
> properties. There should, for example, be a common base class for
> PropertyInfo and FieldInfo called e.g. DataMemberInfo with virtual methods
> such as GetValue(), SetValue(). If you use reflection a lot, it is often a
> pain to have to write parallel code to deal with fields and properties when
> they have a lot of common behaviour from an "outside world" point of view.
I think they have enough differences to distinguish between them,
myself. I suppose I could live with some way of getting both of them, so
long as there was also a way of getting them separately. Of course,
there's nothing to stop you from writing such a utility class - it
wouldn't be as tightly integrated, of course, but it would still
alleviate most of your problems.
(In many cases, I suspect that if you use reflection a lot there's
likely to be something wrong in the design - reflection is powerful, but
probably doesn't need to be used in many of the cases where it *is*
being used.)
> I also don't see much reason (above nomenclature) why public fields shouldn't
> be put in the "property browser". If the language designers are saying
> "never have public fields" then they shouldn't allowed them in the language.
The language designers are saying (I believe): "Public fields are
*usually* (but not always) a bad idea - we'll have them available, but
suggest that people don't use them without due consideration."
Yes, but that doesn't help if you want to force all your code to use the
property instead of the variable, for consistency. Nor does it help if
you want to make the property public for read and protected or internal
(or protected internal) for write.
But since the rule of thumb is "all public data members are properties" then
really the assumption (from outside the class) that you're calling code to
set data members (i.e. using properties) is always there. Of course the
JITter can compile out the calls in a great many cases.
> o Fields don't have separate access for reading and writing.
Not sure what you mean by "access" here... if you mean public/private then
that is also the case for properties of course (i.e. what was originally
asked). If you mean that a property can be write-only and a field can't,
then yes that's true.
> o Fields don't allow you to easily change the way a value is calculated;
> it may be just backed now by a field, but later it could be a database
> lookup, for instance.
Yes, but what I am arguing is that there should be less distinction between
a field and a property to the outside world.
>
> > Personally I think there should be less distinction between fields and
> > properties. There should, for example, be a common base class for
> > PropertyInfo and FieldInfo called e.g. DataMemberInfo with virtual
methods
> > such as GetValue(), SetValue().
>
> I think they have enough differences to distinguish between them,
> myself. I suppose I could live with some way of getting both of them, so
> long as there was also a way of getting them separately.
Yes of course-- you'd still have distinct PropertyInfo and FieldInfo, but
they would have a common base class between themselves and MemberInfo. The
common base class would exhibit their common characteristics.
> Of course, there's nothing to stop you from writing such a utility class -
it
> wouldn't be as tightly integrated, of course, but it would still alleviate
most of your problems.
In practice, this is very far from ideal.
> (In many cases, I suspect that if you use reflection a lot there's
> likely to be something wrong in the design - reflection is powerful, but
> probably doesn't need to be used in many of the cases where it *is*
> being used.)
Well it is very useful if you have a kind of "plug-in" architecture where
you don't know much about anything at compile time. I agree it is not
universally appropriate.
> The language designers are saying (I believe): "Public fields are
> *usually* (but not always) a bad idea - we'll have them available, but
> suggest that people don't use them without due consideration."
I know they are-- but I think that's sitting on the fence, considering that
simple properties of the kind you illustrated are virtually always no more
expensive than fields. I'd rather be dogmatic. I think if a class designer
publishes a field then s/he is-- or at least should be-- making a very
deliberate statement to the client. For example, structs far more commonly
have public data members, and the statement is something along the lines of
"this struct is just a bag of data and doesn't do anything clever with it
when you're not watching."
S.
Well, I prefer to have it put in a convention so that I know the rare
occasions where I *am* using public fields.
> > o Fields don't have separate access for reading and writing.
>
> Not sure what you mean by "access" here... if you mean public/private then
> that is also the case for properties of course (i.e. what was originally
> asked). If you mean that a property can be write-only and a field can't,
> then yes that's true.
Yes, I mean public/private, and I believe it's a deficiency that you
can't do that with properties at the moment.
> > o Fields don't allow you to easily change the way a value is calculated;
> > it may be just backed now by a field, but later it could be a database
> > lookup, for instance.
>
> Yes, but what I am arguing is that there should be less distinction between
> a field and a property to the outside world.
I tend to be in favour of making things distinct :)
> > Of course, there's nothing to stop you from writing such a utility class -
> > it wouldn't be as tightly integrated, of course, but it would still alleviate
> > most of your problems.
>
> In practice, this is very far from ideal.
Why is it "very far" from ideal? I've written some reflection utility
classes before now and found them very handy, with the non-integration
really not being an issue in the long run.
> > (In many cases, I suspect that if you use reflection a lot there's
> > likely to be something wrong in the design - reflection is powerful, but
> > probably doesn't need to be used in many of the cases where it *is*
> > being used.)
>
> Well it is very useful if you have a kind of "plug-in" architecture where
> you don't know much about anything at compile time. I agree it is not
> universally appropriate.
Plug-in architectures should *usually* (IMO) be built around well-known
interfaces. Not always, but usually.
> > The language designers are saying (I believe): "Public fields are
> > *usually* (but not always) a bad idea - we'll have them available, but
> > suggest that people don't use them without due consideration."
>
> I know they are-- but I think that's sitting on the fence, considering that
> simple properties of the kind you illustrated are virtually always no more
> expensive than fields. I'd rather be dogmatic. I think if a class designer
> publishes a field then s/he is-- or at least should be-- making a very
> deliberate statement to the client. For example, structs far more commonly
> have public data members, and the statement is something along the lines of
> "this struct is just a bag of data and doesn't do anything clever with it
> when you're not watching."
And what if I want *exactly* that behaviour, but reference type
semantics rather than value type semantics? That's usually where I use
them.
I can see a lot of merit in it. Of course there are workarounds e.g. two
different properties with a naming convention, along the lines of the public
MyMethod() and private virtual MyMethodImpl() pattern.
The whole thing about properties is they rely on a lot of conventions e.g.
that the getter and setter have the same name (to the language) and that
their semantics are roughly orthogonal. In general I am in favour of
enforcing things through the language structure rather than relying on
conventions.
> I tend to be in favour of making things distinct :)
Sometimes, but there is also the case for information/implementation hiding,
which leads to homogenous interfaces (or base classes) with heterogenous
implementations.
> > In practice, this is very far from ideal.
>
> Why is it "very far" from ideal? I've written some reflection utility
> classes before now and found them very handy, with the non-integration
> really not being an issue in the long run.
It's less extensible, for one thing. Utility classes have their, er,
utility, but they tend to "seal in" behaviour. I realise I am generalizing
here a lot and it's probably just a difference of opinion. The basic problem
is that one can't inject base classes into existing class hierarchies, in
most (all?) OOPs. There is a lot of power in being able to do so, i.e.
extend the behaviour of existing classes in a way that is transparent to the
current clients of those classes.
> Plug-in architectures should *usually* (IMO) be built around well-known
> interfaces. Not always, but usually.
This is preferable if the interfaces to the plug-ins are within your
control. In a "designer" or "scripting" kind of application, when you want
to examine or alter the state of any old object, reflection is more
flexible.
> > For example, structs far more commonly
> > have public data members, and the statement is something along the lines
of
> > "this struct is just a bag of data and doesn't do anything clever with
it
> > when you're not watching."
>
> And what if I want *exactly* that behaviour, but reference type
> semantics rather than value type semantics? That's usually where I use
> them.
I'd go along with that.
Yuk - that's horrible :(
> The whole thing about properties is they rely on a lot of conventions e.g.
> that the getter and setter have the same name (to the language) and that
> their semantics are roughly orthogonal. In general I am in favour of
> enforcing things through the language structure rather than relying on
> conventions.
There are times and places for both, I believe.
> > I tend to be in favour of making things distinct :)
>
> Sometimes, but there is also the case for information/implementation hiding,
> which leads to homogenous interfaces (or base classes) with heterogenous
> implementations.
Sure. However, I would say that most of the time when you should use
public fields, you're using effectively private classes (and in fact
just "internal" is usually a sufficient access modifier), and then I
think it helps to make the distinction.
> > > In practice, this is very far from ideal.
> >
> > Why is it "very far" from ideal? I've written some reflection utility
> > classes before now and found them very handy, with the non-integration
> > really not being an issue in the long run.
>
> It's less extensible, for one thing. Utility classes have their, er,
> utility, but they tend to "seal in" behaviour. I realise I am generalizing
> here a lot and it's probably just a difference of opinion. The basic problem
> is that one can't inject base classes into existing class hierarchies, in
> most (all?) OOPs. There is a lot of power in being able to do so, i.e.
> extend the behaviour of existing classes in a way that is transparent to the
> current clients of those classes.
There's also a lot of danger in that :)
I would expect that such a utility class would easily pay off the time
it took to author it, if you're doing a *lot* of access to properties
and fields, and want to harmonise the access to some extent. It may not
end up being extensible, but it can still be reusable.
> > Plug-in architectures should *usually* (IMO) be built around well-known
> > interfaces. Not always, but usually.
>
> This is preferable if the interfaces to the plug-ins are within your
> control. In a "designer" or "scripting" kind of application, when you want
> to examine or alter the state of any old object, reflection is more
> flexible.
Indeed - but I'd say that's a rarer case than having the interfaces
within your control. (There are hybrid solutions too, of course, where
you mess with an object's properties as part of configuration, but call
some well-known method to tell it to "execute" or whatever.)