Reputation: 4985
This might sound naive, but...
class Widget
{
public int Foo { get; set; }
}
That's cool, and saves some boilerplate against using a backing field, but at that point, isn't it equivalent to simply:
class Widget
{
public int Foo;
}
Seems like it's little more than a public field, though I suppose it looks different under the hood. From a design point, though, what's the advantage of using a property if it doesn't aid encapsulation?
Upvotes: 15
Views: 2575
Reputation: 1003
We use auto-properties if our getters and/or setters doesn't have any custom logic.
Auto-properties also "automatically" defines the "backing fields" for us.
Your class:
public class YourClass {
public int Foo { get; set; }
}
The IL Code:
.class private auto ansi '<Module>'
{
} // end of class <Module>
.class public auto ansi beforefieldinit YourClass
extends [System.Private.CoreLib]System.Object
{
// Fields
.field private int32 '<Foo>k__BackingField' //this is the backing field for your property
.custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Methods
.method public hidebysig specialname
instance int32 get_Foo () cil managed //this is the GETTER of your property
{
.custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2050
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 YourClass::'<Foo>k__BackingField'
IL_0006: ret
} // end of method YourClass::get_Foo
.method public hidebysig specialname
instance void set_Foo (
int32 'value'
) cil managed //this is the SETTER of your property
{
.custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2058
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld int32 YourClass::'<Foo>k__BackingField'
IL_0007: ret
} // end of method YourClass::set_Foo
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2061
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
IL_0006: ret
} // end of method YourClass::.ctor
// Properties
.property instance int32 Foo()
{
.get instance int32 YourClass::get_Foo()
.set instance void YourClass::set_Foo(int32)
}
} // end of class YourClass
Upvotes: -1
Reputation: 539
also, reflection doesn't work differently on properties than it does on variables though, you're working with a MemberInfo (FieldInfo, PropertyInfo, or MethodInfo whichever way you choose).
Upvotes: 2
Reputation: 186
From msdn:
Properties combine aspects of both fields and methods. To the user of an object, a property appears to be a field, accessing the property requires the same syntax.
You can do something like this:
public class Date
{
private int month = 7; // Backing store
public int Month
{
get
{
return month;
}
set
{
if ((value > 0) && (value < 13))
{
month = value;
}
}
}
}
Simply put properties are a lot more versatile.
Upvotes: 0
Reputation: 660493
In addition to the other good answers posted so far:
Upvotes: 9
Reputation: 3566
Upvotes: 0
Reputation: 351698
Because it gives you the potential to add encapsulated logic later without changing the metadata of the class.
Using properties is considered a best practice - automatically implemented properties were designed to take away the tediousness of writing properties to encourage developers to adhere to this best practice
Upvotes: 23