Click to See Complete Forum and Search --> : Why get/set?


diehardii
August 21st, 2008, 08:27 PM
Hi everyone,

I wanted some opinions on something i really don't understand the need for. so i was looking at vs2008's auto-implemented properties, and i don't understand the necessity for them. Then, I started thinking about why even have get/set properties at all if you are just giving public access to a private variable. i understand if you are making it read only, or protecting it, but I don't get a completely public implementation with no logic. Unless the idea is just to maintain style.

So, why have


private int _foo

public int foo
{
get
{
return _foo;
}
set
{
_foo = value;
}
}


When you could just have

public int _foo

and directly access the class number? My reference books say I should do this, and I never really questioned it, but the more I think about it, I just don't get it. Thanks for any opinions.

mehcode
August 21st, 2008, 09:01 PM
There are two things you could do (depending on the version of .Net you have though I am assuming it is .Net 3.0+ so look at the first example).


public class Foo
{
// By the way, the following is termed an automatic property.
// Meaning, you don't need to write a backing variable for it.
public int FooInt
{
get;
private set; // Allows only this class to actually "change" FooInt.
}

public int FooInt2
{
// This allows only read-access to m_FooInt2.
get { return m_FooInt2; }

// The same can be done to allow only write-access (by using only set).
// Though I can't think of a situation where one would do that.
}

private int m_FooInt2;
};


Hope that was helpful. Myself, I normally use the first example, FooInt.

Oh, and the standard get/set that you show on your first post is normally used for if you wanted to perform some code if a client accessed the property. Mostly only used for some kind of indexing to make sure it's inbounds.

EDIT: Forgot to mention, there is no performance difference what-so-ever in chosing one method or the other. Just the first is much more 'clean' to write (in my opinion).

diehardii
August 21st, 2008, 09:31 PM
Hi mehcode,

I agree with you, i totally understand the purpose if you're limiting access, but at least one of my references says that you should make a public member member private and use the the get/set accessors, and that is why MS came out with the autoproperties (to make empty them more brief). I personally have only used the properties when I need to implement logic or restrict access, but I was wondering if anyone wraps every class member that needs public access. Thanks.

Arjay
August 21st, 2008, 09:56 PM
I personally have only used the properties when I need to implement logic or restrict access, but I was wondering if anyone wraps every class member that needs public access. Thanks.Public properties allow you to connect to the properties via data binding whereas public fields do not.

This will be come even more useful as WPF catches on.

In WPF you have control over modifying the standard controls behavior. Binding helps bind the data object to the control.

For example these are two data templates that display different columns based on the type of the tree node.

<HierarchicalDataTemplate DataType="{x:Type bo:CommandNodeSegmentPriority}" ItemsSource="{Binding Path=ChildNodes}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=NodeName}" Padding="2" Background="Transparent" Foreground="White"/>
<TextBlock Grid.Column="1" Text="{Binding Path=Priority}" Padding="2" Background="Transparent" Foreground="White"/>
</Grid>
</HierarchicalDataTemplate>

<HierarchicalDataTemplate DataType="{x:Type bo:CommandNodeSegment}" ItemsSource="{Binding Path=ChildNodes}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=NodeName}" Padding="2" Background="Transparent" Foreground="White"/>
<TextBlock Grid.Column="2" Text="{Binding Path=PartNumber}" Padding="2" Background="Transparent" Foreground="White"/>
<TextBlock Grid.Column="3" Text="{Binding Path=CountFastener}" Padding="2" Background="Transparent" Foreground="White"/>
<TextBlock Grid.Column="4" Text="{Binding Path=CountDrill}" Padding="2" Background="Transparent" Foreground="White"/>
<TextBlock Grid.Column="5" Text="{Binding Path=TimeEstimated, Converter={StaticResource HoursMinutesValueConverter}}" Padding="2" Background="Transparent" Foreground="White"/>
</Grid>
</HierarchicalDataTemplate>

You'll notice the Columns bind to the data using the {Binding ...} syntax.

For example
Text="{Binding Path=NodeName}"
This code binds the Text property of the text box to the NodeName property of the business (or ViewModel) object.

This won't work if the binding target (i.e. NodeName) isn't a property.

It even gets better, you can even apply validation to the properties using the EnterpriseLibrary.Validation validators.

Here are examples of required text validator and regex validator applied to two string properties.

[StringLengthValidator( 0, 250, MessageTemplate = "Description must be less than 250 characters", Ruleset = "Default" )]
public string Description { get { return _description; } set { SetProperty( ref _description, value ); } }

[RegexValidator( @"^(\d{1,3}.\d{1,3}.\d{1,3})$", RegexOptions.IgnorePatternWhitespace, MessageTemplate = "Version Name is required ( NNN.NNN.NNN )", Ruleset = "Default" )]
public string EntityVersionName { get { return _entityVersionName; } set { SetProperty( ref _entityVersionName, value ); } }

Again, this isn't possible with public fields.

compavalanche
August 22nd, 2008, 12:55 AM
I always use getters and setters. Imagine if you have a large software application your writing with multiple developers.

You start your class out that will be used by other team members.

You expose a field to them. They start to use that field all throughout their code. Now you say hmm I want to log whenever someone accesses this field, or now this field is going to be generated somehow.

If you have that field directly in your clients code you no longer have the ability to change the behavior without changing the interface.

To me this is a strong reason to always use getters/setters. You expose the interface and your free to modify it as you see fit.

boudino
August 22nd, 2008, 02:00 AM
There is one major reason: exposing fields to public breaks encapsulation. Encapsulation is a fundamental feature of OOP, without it, you cannot do OOP regardless you are using classes or not.

And one minor reason: properties have different semantics than methods. Properties says, that you are working with data parts of object's contract, that you can feel free to set and get them as you like it without taking care of performance of side effect, because working with properties should not result in object's activity.

And second minor reason: properties allows you to take extra action while value is changed, like fire an event.

Note: public fields make sence only in private nested classes.

diehardii
August 22nd, 2008, 07:12 AM
I always use getters and setters. Imagine if you have a large software application your writing with multiple developers.

You start your class out that will be used by other team members.

You expose a field to them. They start to use that field all throughout their code. Now you say hmm I want to log whenever someone accesses this field, or now this field is going to be generated somehow.

If you have that field directly in your clients code you no longer have the ability to change the behavior without changing the interface.

To me this is a strong reason to always use getters/setters. You expose the interface and your free to modify it as you see fit.

That makes complete sense. Thanks to everyone for answering.

foamy
August 22nd, 2008, 07:24 AM
Public properties allow you to connect to the properties via data binding whereas public fields do not.

I found out about this not long ago...

Is there a way to have VS2005 auto-generate properties? Or is this exclusively a feature of VS2008?

Arjay
August 22nd, 2008, 09:15 AM
Is there a way to have VS2005 auto-generate properties? Or is this exclusively a feature of VS2008?I'm not aware of this feature in VS2008 (or 2005)? Can you explain what it is?

torrud
August 22nd, 2008, 10:15 AM
VS 2005 give you the possibility to encapsulate fields in properties. To do this write your field declaration and open the context menu on the field name. Then choose Refactore->Encapsulate Field...

darwen
August 22nd, 2008, 10:44 AM
There's a code snippet in VS2005 : try entering "prop <tab> <tab>" (i.e. "prop" and hit tab key twice).

Darwen.

Arjay
August 22nd, 2008, 11:25 AM
There's a code snippet in VS2005 : try entering "prop <tab> <tab>" (i.e. "prop" and hit tab key twice).

Darwen.I see. I just tried it in 2008 and it generated
public int MyProperty { get; set; }

In 2005, it generates

private int myVar;

public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}

foamy
August 22nd, 2008, 05:26 PM
Now there's some useful info :)

/Thread hijacking

verifier
August 24th, 2008, 01:37 AM
Maybe I read the thread too fast, but I didnt see anyone talk about validation. I always add validation to the properties.

for example:


public int Age
{
get { return _age; }
set
{
Check.Between(0, 120, value, "Age");
_age = value;
}
}

public string FirstName
get { return _firstName; }
set
{
Check.NotEmpty(value, "FirstName");
Check.Max(40, value, "FirstName");
_firstName = value;
}
}

Arjay
August 24th, 2008, 12:08 PM
Maybe I read the thread too fast, but I didnt see anyone talk about validation. I always add validation to the properties.See post #4.

boudino
August 25th, 2008, 01:34 AM
Yes, I'm disappointend by this, but I'm too lazy to change it. I rather write the whole construct myself, it is not much work.