正确使用C#属性

时间:2010-08-20 14:53:20

标签: c# properties get set

private List<Date> _dates;

public List<Date> Dates
{
    get { return _dates; }
    set { _dates = value; }
}

OR

public List<Date> Dates
{
    get;        
    set;    
}

我一直使用前者,是不正确还是不好的做法?我从未想过我可以使用第二个选项。我喜欢让我的封装变量以下划线开头,所以我可以将它们与方法参数区分开来。而且我总是那样做。

是否有可能使用第一个选项会导致额外的List<Date>对象被实例化,然后整个_datesvalue替换,或者它是否比那更聪明?

此外,哪个是行业中最突出的还是完全主观的?

12 个答案:

答案 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中的逻辑时,编写类会变得更快。

否则,一个并不比另一个好,并且完全相同,只是说没有逻辑地获取和设置属性的值。

最重要的是,您需要熟悉代码。如果它结束了你没有得到任何改进,你喜欢你正在做的事情,而不仅仅是做它。 =)