正确使用C#属性

发布于 2024-09-15 02:56:53 字数 495 浏览 3 评论 0原文

private List<Date> _dates;

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

或者

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

我一直使用前者,这是不正确或不好的做法吗?我从来没有想过我可以只使用第二个选项。我确实喜欢让封装的变量以下划线开头,这样我就可以将它们与方法参数区分开来。我一直都是这样做的。

使用第一个选项是否可能会导致实例化额外的 List 对象,然后将整个 _dates 替换为 value,还是比这更聪明?

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

private List<Date> _dates;

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

OR

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

I have always used the former, is that incorrect or bad practice? It never occurred to me that I could just use the second option. I do like having my encapsulated variables to begin with an underscore so I can distinguish them from method parameters. And I've just always done it that way.

Is it possible that using the first option would result in an extra List<Date> object being instantiated and then the whole of _dates being replaced with value, or is it more intelligent than that?

Also, which is the most prominent in industry or is it totally subjective?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

玩世 2024-09-22 02:58:09

据我所知,我总是从对象内部管理列表属性,使它们只读。

private IList<DateTime> _dates;

public MyClass() {
    _dates = new List<DateTime>();
}

public IList<DateTime> Dates {
    get {
        return _dates;
    }
}

通过这样做,我可以确保我的列表在访问时永远不会为空,因为客户端无法分配它。

但是,对于您的示例,如果您在获取或设置属性时需要某种逻辑,则只需使用前一种方法。否则,自动属性的作用与您完全相同,只是获取和设置私有字段的值。此外,{ get;放;以我的拙见,提高了可读性并帮助其他程序员理解您的意图。

例如:

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 内部不需要任何逻辑时,编写类代码会变得更快。

否则,一个并不比另一个更好,而且做得完全相同,只是简单地获取和设置属性的值,没有任何逻辑。

最重要的是,您需要对自己的代码感到满意。如果最终你没有得到任何改进,而你喜欢你正在做的事情,那么就去做吧。 =)

As far as I can remember, I have always managed my list properties from within my object, making them readonly.

private IList<DateTime> _dates;

public MyClass() {
    _dates = new List<DateTime>();
}

public IList<DateTime> Dates {
    get {
        return _dates;
    }
}

By doing so, I assure that my list is never null when I access it, since the client cannot assign it.

However, for your example, you only need to use the former approach if you need some kind of logic when getting or setting a property. Otherwise, automatic properties does exactly the same you would, only getting and setting a value to a private field. Furthermore, the { get; set; } improves readability and helps other programmers understand your intention, in my humble point of view.

For instance:

public class MyClass {
    private IList<DateTime> _dates;

    public IList<DateTime> Dates {
        get {
            return _dates;
        } set {
            _dates = value;
        } 
    }
}

versus

public class MyClasse {
    public IList<DateTime> Dates { get; set; }
}

The second way makes it leaner and swifter, at least to me, what the intention is. And it becomes faster to code a class, when no logic inside the getter and setter is necessary.

Otherwise, one is not better than the other and does quite the same, speaking of getting and setting simply the property's value with no logic.

Most importantly, you need to be comfortable with your code. If it ends for you not getting any improvements, and you like what you're doing, than just do it. =)

秋意浓 2024-09-22 02:58:00

两者的编译方式大致相同(我不知道支持字段的名称是否具体相同,但它们在功能上是等效的)。

IIRC,.NET 3.0 或 3.5 中添加了执行自动属性(public ListDates {get; set;})的功能。

The two are compiled roughly the same way (I don't know that the backing field's name would specifically be the same, but they'd be functionally equivelant).

IIRC, the ability to do Automatic Properties (public List<Date> Dates {get; set;}) was added in either .NET 3.0 or 3.5.

瑕疵 2024-09-22 02:57:51

我相信它们编译成相同的代码。后者只是代表前者的语法糖。我倾向于将后者视为未来可能需要放置在属性中的逻辑的占位符,此时我会将所述受影响的属性转换为前者。

I believe they compile to the same code. The latter is just syntactic sugar to represent the former. I tend to think of the latter as a placeholder for future logic that may need to be placed in the properties, at which point I'd convert said affected properties to the former.

偷得浮生 2024-09-22 02:57:49

只要您不必确保 List 在 getter 中初始化,您就可以使用这两个版本。我只是建议您使用一个版本,并且不要将其混合在代码中...

如果您需要初始化它,则必须使用第一个版本...

private List<Date> _dates; 

public List<Date> Dates 
{ 
    get { if (_dates == null) _dates = new List<Date>(); return _dates; } 
    set { _dates = value; } 
} 

As long as you don't have to make sure the List<Date> is initialized in the getter you are fine with both versions. I just suggest that you are using one version and you don't mix it in your code...

If you need it initialized you have to go for the first version...

private List<Date> _dates; 

public List<Date> Dates 
{ 
    get { if (_dates == null) _dates = new List<Date>(); return _dates; } 
    set { _dates = value; } 
} 
指尖上的星空 2024-09-22 02:57:47

没关系。第二种只是糖。我总是使用第二个,因为它更干净,但每隔一段时间我就需要访问支持值。

It doesn't matter. The second is just sugar. I always use the second because it's cleaner, but every once in a while I need access to the backing value.

孤独陪着我 2024-09-22 02:57:44

我个人更喜欢第一种方法,因为它允许您在返回之前执行一些操作。

EG(一个非常糟糕的例子)

    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;
           }
       }
    }

I personally prefer the first method as it allows you to perform a few operations prior to the return.

E.G. (A really poor example)

    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;
           }
       }
    }
别再吹冷风 2024-09-22 02:57:40

第二种变体称为自动实现的属性,并在C#3.0(因此您以前可能没有遇到过它)。

如果您想创建带有支持字段的简单属性并且不需要在“getter”和“setter”中实现任何逻辑,则最好使用此格式。它不仅更简洁,而且还强制您直接访问该属性,而不是通过支持字段,这通常是最佳实践。

请注意,您仍然可以初始化属性,只需通过构造函数即可完成。

public class MyClass
{

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

  public MyClass()
  {
      Dates = new List<Date>();
  }

}

The second variation is know as auto-implemented properties and was introduced in C#3.0 (hence why you may not have encountered it before).

It is preferable to use this format if you want to create simple properties with backing-fields and don't need to implement any logic in the 'getter' and 'setter'. Not only is it more concise, but it also forces you to access the property directly, rather than going through the backing field, which is normally best practice.

Note you can still initialise properties, you just do it via the constructor.

public class MyClass
{

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

  public MyClass()
  {
      Dates = new List<Date>();
  }

}
逆光飞翔i 2024-09-22 02:57:37

前者是原始方法,后者是较新的“自动属性”工具的示例,编译器可以通过该工具自动为您生成支持字段。

有些人(包括我自己)回避自动属性,因为语法很容易被误认为是抽象属性,没有“只读”属性的工具,并且带有私有设置器的自动属性的语法很笨拙:

public List Dates
{
    get;
    private set;
}

我也发现拥有我的类的内部实现通过类 API 访问字段。

The former is the original approach, the latter is an example of the newer 'auto properties' facility whereby the compiler generates a backing field for you automatically.

Some people (myself included) shy away from auto properties because the syntax is easy to mistake for abstract properties, there is no facility for 'readonly' properties and the syntax for auto properties with private setters is clumsy:

public List Dates
{
    get;
    private set;
}

I also find it uncomfortable to have my classes' internal implementation accessing fields via the class API.

回忆追雨的时光 2024-09-22 02:57:35

我倾向于更多地使用自动属性,因为属性是表达对象正在做什么的意图的好方法,但仍然有一些保护。

几乎我所有的属性声明都是这样的:

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;
    }
}

I tend to use auto properties more because a property is a good way to express intent about what your object is doing, but still have some protection.

Almost all of my property declarations look like:

public bool IsBlah { get; private set; }

This makes it a nice, readable, and protected getter.

But there are times when you want an explicit backing field:

private bool? _isBlah;
public bool IsBlah
{
    get
    {
        if (_isBlah == null)
        {
            // Do something expensive here and set _isBlah
            _isBlah = true;
        }
        return _isBlah;
    }
}
辞别 2024-09-22 02:57:33

由于 .NET 编译自动属性的方式不同,两者基本相同。 .NET 3.5 中提供了自动属性。

Both are basically the same because of how .NET compiles automatic properties. Automatic properties became available with .NET 3.5.

清风挽心 2024-09-22 02:57:30

它们在内部编译形式中是等效的,只是您无法在第二种形式中访问编译器生成的私有变量。

从代码效率的角度来看,它们也是等效的,即时编译器通常直接访问私有变量,而无需调用访问函数的开销(在运行时环境检查可访问性等之后)。

从编码的角度来看,我更喜欢第二个版本,它更紧凑(编写更少,阅读更少)。

第二种语法是在 C# 3.0 中引入的。因此第一个变体将更兼容旧的编译器。

They are equivalent in the internal compiled form, except that you cannot access the compiler generated private variable in the second form.

From a code efficiency point of view, they are equivalent as well, the just in time compiler normally directly accesses the private variable without the overhead of calling an access function (after the runtime environment has checked accessibility etc.).

From a coding perspective, I prefer the second version which is more compact (less to write, less to read).

The second syntax was introduced in C# 3.0. So the first variant would be more compatible to old compilers.

糖粟与秋泊 2024-09-22 02:57:24

如果您需要向 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; }
}

Use the former if you need to add some kind of logic to your getter/setters.

Use the latter otherwise. It makes things much cleaner. You can also achieve read-only properties using auto properties:

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

Or, if you don't want people to add any items to the list through the property you can resort to the former syntax:

private List<Date> _dates = new List<Date>();
private ReadOnlyCollection<Date> _readOnlyDates =
    new ReadOnlyCollection<Date>(_dates);

public ReadOnlyCollection<Date> Dates
{
    get { return _readOnlyDates; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文