private List<Date> _dates;
public List<Date> Dates
{
get { return _dates; }
set { _dates = value; }
}
OR
public List<Date> Dates
{
get;
set;
}
我一直使用前者,是不正确还是不好的做法?我从未想过我可以使用第二个选项。我喜欢让我的封装变量以下划线开头,所以我可以将它们与方法参数区分开来。而且我总是那样做。
是否有可能使用第一个选项会导致额外的List<Date>
对象被实例化,然后整个_dates
被value
替换,或者它是否比那更聪明?
此外,哪个是行业中最突出的还是完全主观的?
答案 0 :(得分:19)
如果您需要为getter / setter添加某种逻辑,请使用前者。
否则使用后者。它使事情变得更加清洁。您还可以使用自动属性实现只读属性:
public List<Date> Dates { get; private set; }
或者,如果您不希望人们通过属性向列表中添加任何项目,您可以采用以前的语法:
private List<Date> _dates = new List<Date>();
private ReadOnlyCollection<Date> _readOnlyDates =
new ReadOnlyCollection<Date>(_dates);
public ReadOnlyCollection<Date> Dates
{
get { return _readOnlyDates; }
}
答案 1 :(得分:7)
两者基本相同,因为.NET编译自动属性。 .NET 3.5提供了自动属性。
答案 2 :(得分:7)
它们在内部编译形式中是等效的,除了你不能以第二种形式访问编译器生成的私有变量。
从代码效率的角度来看,它们也是等价的,即时编译器通常直接访问私有变量而没有调用访问函数的开销(在运行时环境检查了可访问性等之后)。
从编码的角度来看,我更喜欢第二个版本,它更紧凑(写入更少,阅读量更少)。
第二种语法是在C#3.0中引入的。因此,第一个变体将与旧编译器更兼容。
答案 3 :(得分:4)
我倾向于更多地使用自动属性,因为属性是表达对象正在做什么的意图的好方法,但仍然有一些保护。
我的几乎所有财产声明都是:
public bool IsBlah { get; private set; }
这使它成为一个漂亮,可读且受保护的getter。
但有时您需要明确的支持字段:
private bool? _isBlah;
public bool IsBlah
{
get
{
if (_isBlah == null)
{
// Do something expensive here and set _isBlah
_isBlah = true;
}
return _isBlah;
}
}
答案 4 :(得分:1)
前者是原始方法,后者是较新的“自动属性”工具的示例,编译器会自动为您生成支持字段。
有些人(包括我自己)回避了自动属性,因为语法很容易被误认为是抽象属性,没有“readonly”属性的功能,而私有setter的自动属性的语法是笨拙的:
public List Dates
{
get;
private set;
}
我还发现让我的类的内部实现通过类API访问字段感到不舒服。
答案 5 :(得分:1)
第二种变体被称为auto-implemented properties,并在C#3.0中引入(因此您可能以前没有遇到过它)。
如果要使用后备字段创建简单属性并且不需要在“getter”和“setter”中实现任何逻辑,则最好使用此格式。它不仅更简洁,而且还会迫使您直接访问该属性,而不是通过支持字段,这通常是最佳做法。
请注意,您仍然可以初始化属性,只需通过构造函数即可。
public class MyClass
{
public List<Date> Dates
{
get;
set;
}
public MyClass()
{
Dates = new List<Date>();
}
}
答案 6 :(得分:1)
我个人更喜欢第一种方法,因为它允许你在返回之前执行一些操作。
E.G。 (一个非常糟糕的例子)
private int _limit;
private int _onHand;
private bool returnToVendor;
public Item(int limit, int onHand)
{
_limit = limit;
_onHand = onHand;
}
public int ReturnStock
{
get
{
if(_onHand > _limit)
{
returnToVendor = true;
return _onHand;
}
}
set
{
_onHand = value;
if(_onHand < _limit)
{
returnToVendor = false;
}
}
}
答案 7 :(得分:0)
没关系。第二个只是糖。我总是使用第二种,因为它更干净,但每隔一段时间我就需要访问支持值。
答案 8 :(得分:0)
只要您不必确保在getter中初始化List<Date>
,您就可以使用这两个版本。我只是建议您使用一个版本而不要在代码中混合使用...
如果您需要初始化,则必须使用第一个版本...
private List<Date> _dates;
public List<Date> Dates
{
get { if (_dates == null) _dates = new List<Date>(); return _dates; }
set { _dates = value; }
}
答案 9 :(得分:0)
我相信他们编译成相同的代码。后者只是代表前者的语法糖。我倾向于认为后者是未来逻辑的占位符,可能需要放置在属性中,此时我将所述受影响的属性转换为前者。
答案 10 :(得分:0)
这两个编译方式大致相同(我不知道支持字段的名称将特别相同,但它们在功能上是等同的。)
IIRC,在.NET 3.0或3.5中添加了自动属性(public List<Date> Dates {get; set;}
)的功能。
答案 11 :(得分:0)
据我所知,我总是从我的对象中管理我的列表属性,使它们只读。
private IList<DateTime> _dates;
public MyClass() {
_dates = new List<DateTime>();
}
public IList<DateTime> Dates {
get {
return _dates;
}
}
通过这样做,我确保当我访问它时,我的列表永远不会为空,因为客户端无法分配它。
但是,对于您的示例,如果在获取或设置属性时需要某种逻辑,则只需使用前一种方法。否则,自动属性与您完全相同,只是获取并将值设置为私有字段。此外,{ get; set; }
以简洁的观点提高了可读性,并帮助其他程序员理解您的意图。
例如:
public class MyClass {
private IList<DateTime> _dates;
public IList<DateTime> Dates {
get {
return _dates;
} set {
_dates = value;
}
}
}
与
public class MyClasse {
public IList<DateTime> Dates { get; set; }
}
第二种方式使它更精简,更快,至少对我来说,意图是什么。当没有必要使用getter和setter中的逻辑时,编写类会变得更快。
否则,一个并不比另一个好,并且完全相同,只是说没有逻辑地获取和设置属性的值。
最重要的是,您需要熟悉代码。如果它结束了你没有得到任何改进,你喜欢你正在做的事情,而不仅仅是做它。 =)