这听起来可能很幼稚,但是...
class Widget
{
public int Foo { get; set; }
}
这很酷,并且为使用支持字段节省了一些样板,但在这一点上,它不等同于简单地:
class Widget
{
public int Foo;
}
似乎它只不过是一个公共领域,尽管我认为它在引擎盖下看起来不同。但是,从设计的角度来看,如果属性不帮助封装,那么使用属性有什么好处呢?
这听起来可能很幼稚,但是...
class Widget
{
public int Foo { get; set; }
}
这很酷,并且为使用支持字段节省了一些样板,但在这一点上,它不等同于简单地:
class Widget
{
public int Foo;
}
似乎它只不过是一个公共领域,尽管我认为它在引擎盖下看起来不同。但是,从设计的角度来看,如果属性不帮助封装,那么使用属性有什么好处呢?
因为它使您有可能在以后添加封装逻辑而不更改类的元数据。
使用属性被认为是最佳实践 - 自动实现的属性旨在消除编写属性的繁琐,以鼓励开发人员遵守此最佳实践
除了到目前为止发布的其他好的答案:
此外,反射在属性上的工作方式与在变量上的工作方式没有什么不同,但您正在使用 MemberInfo(FieldInfo、PropertyInfo 或 MethodInfo,无论您选择哪种方式)。
来自msdn:
属性结合了字段和方法的各个方面。对于对象的用户来说,属性似乎是一个字段,访问该属性需要相同的语法。
你可以这样做:
public class Date
{
private int month = 7; // Backing store
public int Month
{
get
{
return month;
}
set
{
if ((value > 0) && (value < 13))
{
month = value;
}
}
}
}
简而言之,属性更加通用。
如果我们的 getter 和/或 setter 没有任何自定义逻辑,我们将使用自动属性。
自动属性还“自动”为我们定义“支持字段”。
你的班:
public class YourClass {
public int Foo { get; set; }
}
IL代码:
.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