开发者

Which is more correct and why?

开发者 https://www.devze.com 2023-02-19 14:34 出处:网络
Which is better implementation or there is no difference? 1. public class Simple { public IList<string> Entries { get; private set; }

Which is better implementation or there is no difference?

1.

public class Simple
{
    public IList<string> Entries { get; private set; }

    public Simple()
    {
        Entries = new List<string>();
    }
}

or 2.

public class Simple
{
    private readonly IList<string> entries = 开发者_运维知识库new List<string>();
    public IList<string> Entries { get { return entries; } }
}


I'll assume that for the second version you meant:

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}

Note that I've made the entries variable readonly.

If that's what you meant, because you don't need to reassign the variable anywhere in the class (other than possibly in constructors) then I think this is preferable to the automatic property version.

It shows the clear intent that this is meant to be read-only - whereas the automatic property only shows that it's meant to be read-only to the outside world. Someone (perhaps you) might end up changing the value of the automatic property from within the class later on, forgetting that the original design was for this to be a read-only property.

(Of course, we're not really talking about full immutability anyway, as anyone can add or remove entries from the list.)

If you really want to be able to change the property value within the class, definitely use the first version.

Having expressed a preference for the readonly field version, in practice I've found myself using the automatic property because it's less code to read and write. I've felt dirty every time I've done it though. Ideally I'd like a way of creating a readonly automatically implemented property which can only be set in the constructor, just like a readonly field. (The property would be backed by a readonly field, and setter calls would be compiled directly into field assignments.) I haven't heard of any plans for this sort of thing to actually happen though.


There is no real practical difference (#2 won't compile, you need to leave out the setter).

As long as you don't need logic in the getter, and don't need to access the field directly, it is a matter of style.

I'd prefer the automatic property version because (I feel) it is slightly simpler, and refactor to a property with backing field when needed.


If you store the list in a field you can mark the field as readonly, to make sure you don't alter the field inside the class either.

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}


Option #2 won't compile in the first place.

Other than that, in option #2 you can omit the set accessor altogether. This will make, for instance, PropertyInfo.CanWrite return false.


Options #1 is better since in second you also probably missed readonly keyword.


I prefer the second approach. This way the list is available to you before your constructors run. The advantage is that if you were to add more class constructors, etc, you don't have to worry / remember about newing up the list over and over.


There is no real differences, neither in the API you are exposing nor in the semantics in the code (ok the first one allows you to overwrite the Entries variable at a later time, which you probably don't want).

Most of the difference is in the syntax which is just a matter of taste.


Go with whichever is more readable for you (or, if you're writing code for a project with a consistent style, be consistent).

They're pretty much the same (I assume you meant to declare the instance variable in the second example private and omit the setter), but one thing to note is that auto-implemented properties can't be marked readonly. This is a pretty neat feature that doesn't seem to be used as much as it should, unfortunately.

In any case, as far as any other classes are concerned, they're identical, so if you do decide to change your mind, it's a very trivial change. So go with what works and don't sweat it too much -- this isn't an area where a single style is really the "established norm" yet.

Personally, I use the second only when I have a readonly variable, and the first otherwise (it's less typing). Hey Anders, how about auto-implemented readonly properties?

Edit

The edited question has a much simpler answer: if the field is readonly, mark it as readonly. The only way to do this is the second way.

Not distinguishing readonly properties isn't a cardinal sin or anything, but it's definitely less clear than distinguishing them (and may even help to prevent some bugs).


The first compiles into the equiovolent of this IL anyway:

public class Simple{    
  private IList<string> entries;

  public IList<string> Entries { 
    get { return entries; }
  } 

  public Simple() {
    entries= new List<string>();    
  }
}

So the only difference between them is that your first allows the instance to change the reference to a different collection if it wants, the other doesn't.

This would be the equivolent of the second method:

public class Simple{    
  private readonly IList<string> entries;

  public IList<string> Entries { 
    get { return entries; }
  } 

  public Simple() {
    entries= new List<string>();    
  }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消