Why simple properties?

  • Thread starter Thread starter pinkfloydhomer
  • Start date Start date
P

pinkfloydhomer

I can understand why properties are neat if you want to limit access
(only get, no set), or you want to do some bookkeeping or sanity
checking on values (in set) or if you want to change the underlying
type without changing the property type etc.

But what is the use for properties like:

private int data;

public int Data
{
get
{
return data;
}

set
{
data = value;
}
}


?

I see this a lot. For all intents and purposes, you might just have a
public member instead. Even if you wanted to change the public member
later to a property, your interface would still be maintained. No
possibilities lost.

/David
 
On Oct 3, 10:28 am, "(e-mail address removed)"

I see this a lot. For all intents and purposes, you might just have a
public member instead. Even if you wanted to change the public member
later to a property, your interface would still be maintained. No
possibilities lost.

No, the interface isn't maintained. There are various things you can
do with fields (such as passing them by reference) which you can't do
with properties. Likewise there are things which work with properties
(such as databinding) which don't work with fields. Anything using
reflection or serialization is likely to break as well.

It's best to use properties right from the start - I don't like having
any fields which aren't private. I see that it's a slight pain to have
the whole property code, but C# 3 will make this simpler:

public string Foo { get; private set; }

for instance.

Jon
 
I can understand why properties are neat if you want to limit access
(only get, no set), or you want to do some bookkeeping or sanity
checking on values (in set) or if you want to change the underlying
type without changing the property type etc.

But what is the use for properties like:

private int data;

public int Data
{
get
{
return data;
}

set
{
data = value;
}

}

?

I see this a lot. For all intents and purposes, you might just have a
public member instead. Even if you wanted to change the public member
later to a property, your interface would still be maintained. No
possibilities lost.

/David

Hi David,
In addition to what Jon said, I also find it handy to have the
property accessors as a central place to set a breakpoint (or add log
line) to help in debugging.
John
 
As an addition to what other people have said, consider that your
current needs may also not be your future needs. Are you really going to
want to go through everything and change your variable use to property
use if you decide you do need some kind of sanity checking/other things
going on whenever that property is assigned? Personally, I think it
helps a bit with future-proofing as well.

Chris.
 
Jon Skeet said:
No, the interface isn't maintained. There are various things you can
do with fields (such as passing them by reference) which you can't do
with properties. Likewise there are things which work with properties
(such as databinding) which don't work with fields. Anything using
reflection or serialization is likely to break as well.

I never quite thought of that, but you're completly right.

I'll remember these reasons, as I see this come up quite often during code
reviews. I kick code back with "Make these properties" and a debate then
begins.
 
John Duval said:
In addition to what Jon said, I also find it handy to have the
property accessors as a central place to set a breakpoint (or add log
line) to help in debugging.

Just to be nitpicky (sorry, I can't help myself!), you can do both of those
with a variable as well.

Set a breakpoint on the variable, right click on the little red circle, and
select "When hit". Up will come a dialog box that lets you do all sorts of
fun. It's quite powerful, and is a big aid to debugging (as are all the
'Advanced' breakpoint functions).

Of course, you can do all this with a property accessor too, but even then I
often end up setting the breakpoint on the variable itself, in case
something unforseen is going on...
 
I can understand why properties are neat if you want to limit access
(only get, no set), or you want to do some bookkeeping or sanity
checking on values (in set) or if you want to change the underlying
type without changing the property type etc.

But what is the use for properties like:

private int data;

public int Data
{
get
{
return data;
}

set
{
data = value;
}

}

?

I see this a lot. For all intents and purposes, you might just have a
public member instead. Even if you wanted to change the public member
later to a property, your interface would still be maintained. No
possibilities lost.

Yeah, you are right. Public instance variables are very convienient,
e.g. in small struct-like classes whose only purpose is to package
some data fields. There's no need to clutter the code with endless
getters and setters.

Also, from a design vs. implementation viewpoint it makes sense. An
entity has some properties (in the common language sense) and these
may be implemented as either properties (in the C# sense) or public
fields. Actually, I cannot see why this should not be possible:

interface DaInterface
{
int Something {get; set;}
}

class ImplementerClass : DaInterface
{
public int Something;
}
 
Yeah, you are right. Public instance variables are very convienient,
e.g. in small struct-like classes whose only purpose is to package
some data fields. There's no need to clutter the code with endless
getters and setters.

You mean apart from proper encapsulation? Variable names are an
implementation detail, IMO.
Also, from a design vs. implementation viewpoint it makes sense. An
entity has some properties (in the common language sense) and these
may be implemented as either properties (in the C# sense) or public
fields. Actually, I cannot see why this should not be possible:

interface DaInterface
{
int Something {get; set;}
}

class ImplementerClass : DaInterface
{
public int Something;
}

Because DaInterface has specified a property, and it isn't being
implemented in the ImplementerClass. Yes, C# *could* generate a
property instead, but that would give two very different syntaxes for
properties.

In C# 3 life will be much simpler though:

public int Something { get; set; }
 
You mean apart from proper encapsulation? Variable names are an
implementation detail, IMO.

For a read-write property the underlying field is exposed to the
outside and there isn't any encapsulation to care about. One might as
well make the field public. This gives clearer, crisper and easier to
maintain code. The rule "Never use public fields" isn't proper
encapsulation. Proper encapsulation is to hide fields that are not
needed from the outside, but also to realize that once in a while some
internal data of an object must be exposed and public fields are a
good candidate to implement this behavior.
Because DaInterface has specified a property, and it isn't being
implemented in the ImplementerClass. Yes, C# *could* generate a
property instead, but that would give two very different syntaxes for
properties.

If some property should be a simple read-write property doing nothing
but copying the value, then why not just implement it as a public
field? One might speculate that maybe in the future the distinction
between field and property will disappear, "field" would just be
shorthand for a non-restricted property with no method body.
In C# 3 life will be much simpler though:

public int Something { get; set; }

Ok, that looks neat. But, still, I would read that as: Something is
like a public field. And I would then erase the curly braces thing,
because it's redudant.
 
For a read-write property the underlying field is exposed to the
outside and there isn't any encapsulation to care about.

No - the field's *value* is exposed, but not the field itself. I can
rename the field to my heart's content - it's an implementation
detail.
One might as
well make the field public. This gives clearer, crisper and easier to
maintain code. The rule "Never use public fields" isn't proper
encapsulation. Proper encapsulation is to hide fields that are not
needed from the outside, but also to realize that once in a while some
internal data of an object must be exposed and public fields are a
good candidate to implement this behavior.

Only if you deem the fact that it's directly stored as a field without
even the *potential* for validation or other storage as part of the
specification. I think that locks things down too much, personally.

I believe that a field is too low-level a concept to be part of the
exposed API for a well-designed component.
If some property should be a simple read-write property doing nothing
but copying the value, then why not just implement it as a public
field? One might speculate that maybe in the future the distinction
between field and property will disappear, "field" would just be
shorthand for a non-restricted property with no method body.

I think that's very unlikely, seeing as they're logically different
things. A field is a storage location; a property is way of accessing
data. Changing between the two changes behaviour in various ways -
code using a read/write field may not compile when using a property
(think "pass by reference"), reflection will see different things,
etc.
Ok, that looks neat. But, still, I would read that as: Something is
like a public field. And I would then erase the curly braces thing,
because it's redudant.

But it's *not* a public field. There's a different in the metadata,
there are different semantics in various ways. Why try to pretend it's
something it's not?

Jon
 
Just to be nitpicky (sorry, I can't help myself!), you can do both of those
with a variable as well.

Set a breakpoint on the variable, right click on the little red circle, and
select "When hit". Up will come a dialog box that lets you do all sorts of
fun. It's quite powerful, and is a big aid to debugging (as are all the
'Advanced' breakpoint functions).

Of course, you can do all this with a property accessor too, but even then I
often end up setting the breakpoint on the variable itself, in case
something unforseen is going on...

Hi Chris,
Not sure I follow what you mean. If you have two classes like this:

public class TestClass1
{
public string TestValue; // breakpoint can NOT be set
}

public class TestClass2
{
private string _testValue;
public string TestValue { set { _testValue = value; } } //
breakpoint can be set
}

You can set a breakpoint whenever TestValue is set on TestClass2, but
you can't do it for TestClass1. Are we talking about the same thing?

And I agree about the "When Hit..." breakpoint options, they're very
useful.
John
 
John Duval said:
Hi Chris,
Not sure I follow what you mean. If you have two classes like this:

public class TestClass1
{
public string TestValue; // breakpoint can NOT be set
}

public class TestClass2
{
private string _testValue;
public string TestValue { set { _testValue = value; } } //
breakpoint can be set
}

You can set a breakpoint whenever TestValue is set on TestClass2, but
you can't do it for TestClass1. Are we talking about the same thing?

And I agree about the "When Hit..." breakpoint options, they're very
useful.
John

Also, data breakpoints only work in native code, because if the garbage
collector moves the object... MS needs to get their debugging act together
and make the GC update breakpoint registers pointing into the managed heap.
 
Jon Skeet said:
No - the field's *value* is exposed, but not the field itself. I can
rename the field to my heart's content - it's an implementation
detail.

You cannot rename the public member. Fields and properties are alike in
that regard.
Only if you deem the fact that it's directly stored as a field without
even the *potential* for validation or other storage as part of the
specification. I think that locks things down too much, personally.

I believe that a field is too low-level a concept to be part of the
exposed API for a well-designed component.

Even for something like System.Drawing.Point?

What about interop structures?
 
You cannot rename the public member. Fields and properties are alike in
that regard.

Yes - but it's not the same as what was claimed - that "for a read-
write property
the field is exposed to the outside".
Even for something like System.Drawing.Point?

Yes. In fact, that's a good example - in Java, the Point class exposes
the fields directly. They are integers. When a Point with more
precision was required, a new class had to be created using doubles.
If the Point class had exposed properties instead, the existing
properties could have been kept as integers, the underlying fields
could have been changed to doubles, and new properties could have
exposed the extra precision.
What about interop structures?

They *may* be an exception, because the storage (which is usually an
implementation detail) becomes effectively part of the API. I try to
avoid interop where possible :)

Jon
 
FWIW: I would like to see something to make these properties less verbose;
e.g.

public property string Name;
public property int Age;
public property bool Male;

This would just be a compiler directive to create the variables name, age,
and male, as well as the get and set as usual. You could even comment it in
the usual way. This saves a HUGE amount of code and also eliminates the
potential recursive bug.

Hilton
 
FWIW: I would like to see something to make these properties less verbose;
e.g.

public property string Name;
public property int Age;
public property bool Male;

This would just be a compiler directive to create the variables name, age,
and male, as well as the get and set as usual. You could even comment it in
the usual way. This saves a HUGE amount of code and also eliminates the
potential recursive bug.

As I've said, C# 3 has this, but with a slightly different syntax
which avoids introducing any new keywords and still allows different
access for getters/setters. The variable itself is invisible to the
code - it can only use the property.

What C# 3 *doesn't* have (but I'd like) is a way of having custom code
in the property but still hide the variable:

public int Age
{
int age;
// Put more code in here if you want
get { return age; }
set { age = value; }
}

The compiler could still force uniqueness of variable name, but
prohibit access to the variable outside the property - possibly with
exceptions for things like serialization (with an attribute for
methods which want direct access, for instance).

That way the rest of the class is forced to use the property as well,
which aids encapsulation further.

No CLR change would be required for this, which is always nice :)

Jon
 
For a read-write property the underlying field is exposed to the
outside and there isn't any encapsulation to care about. One might as
well make the field public. This gives clearer, crisper and easier to
maintain code. The rule "Never use public fields" isn't proper
encapsulation.

I suppose that depends on your definition of "encapsulation". But the
definition I use definitely includes "never use public fields" as a
mechanism to achieve encapsulation.

The field is an implementation detail. The property is the behavior
exposed by the class. Proper encapsulation hides implementation details
while preserving behaviors. By hiding implementation details, the class
implementation can change arbitrarily, and as long as the class
continues to provide its publicly declared behavior, there's no problem.

There is no way to change from a public field to a public property after
the fact. The difference between the field and a property is a
_behavioral_ difference, and only by changing the _behavior_ of the
class can you modify that part of the design of the class.

But if you use a property from the outset, you can modify your
implementation however you like without having to change the behavior.
This is what encapsulation is all about, and that's why never using
public fields when you can instead use a property is very much part of
proper encapsulation.
Proper encapsulation is to hide fields that are not
needed from the outside,

See, here's the fundamental difference in opinion: you believe that
encapsulation is only about "hiding" things that "are not needed from
the outside".

That's certainly one way to describe it, but it's my opinion that
encapsulation is different from that. The difference is subtle,
granted. But IMHO it's a very real difference.
but also to realize that once in a while some
internal data of an object must be exposed and public fields are a
good candidate to implement this behavior.

Well, how about that? I would agree that if "some internal data of an
object must be exposed", then you have to expose it and you have to use
public field to do that. But when does that actually happen? Can you
provide an example?

I'll start out with the obvious one: a class that is actually more like
a struct, and doesn't really have any behavior but is rather just a
place to keep data. All such a class would have is a bunch of public
fields and perhaps a constructor. I agree, no real need for properties
there.

But other than that degenerate class example, in what case is it true
that "some internal data of an object MUST be exposed"?

Pete
 
No, the interface isn't maintained. There are various things you can
do with fields (such as passing them by reference) which you can't do
with properties. Likewise there are things which work with properties
(such as databinding) which don't work with fields. Anything using
reflection or serialization is likely to break as well.

Okay. Seems like kind of an random implementation artifact, and not
some deep language reason.
It's best to use properties right from the start - I don't like having
any fields which aren't private.

In situations where you just want people to be able to access the data
(in simple structs only for holding data etc.), exactly the situations
in which you would make "simple properties" as I called them, and in
which you are fairly sure that this will never change, properties are
just syntactic clutter, IMO. That might change with C# 3.0.

/David
 
You mean apart from proper encapsulation? Variable names are an
implementation detail, IMO.

This has nothing to do with proper encapsulation. Both solutions has
exactly the same degree of encapsulation.
Also, property names are just as much an implementation detail as is
an variable name.

/David
 
Yes. In fact, that's a good example - in Java, the Point class exposes
the fields directly. They are integers. When a Point with more
precision was required, a new class had to be created using doubles.
If the Point class had exposed properties instead, the existing
properties could have been kept as integers, the underlying fields
could have been changed to doubles, and new properties could have
exposed the extra precision.

But that is precisely because of the seemingly random implementation
choice that properties must be something different than fields. I
can't see why it wouldn't be a better solution to say that a property
has the same interface as a field. Then, if the above situation
happened, you could silently change your fields to properties and
change the type of the underlying fields. I can't see how it is not a
weakness and a random implementation artifact, that this is not
possible.

/David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top