开发者

Why can't properties be readonly?

This 开发者_StackOverflow社区question came up in the comments of this answer. The inability to have readonly properties was proposed as a potential reason to use fields instead of properties.

For example:

class Rectangle
{
   private readonly int _width;
   private readonly int _height;

   public Rectangle(int width, int height)
   {
      _width = width;
      _height = height;
   }

   public int Width { get { return _width; } }
   public int Height { get { return _height; } }
}

But why can't you just do this?

public int Width { get; readonly set; }

Edit (clarification): You can achieve this functionality in the first example. But why can't you use the auto-implemented property shorthand to do the same thing? It would also be less messy, since you wouldn't have to directly access the fields in your constructor; all access would be through the property.

Edit (update): As of C# 6.0, readonly properties are supported! object MyProp { get; } This property can be set inline (object MyProp { get; } = ...) or in the constructor, but nowhere else (just like readonly fields).


Because the language doesn't allow it.

This may seem like a frivolous answer: after all, the language designers could have declared that if you used readonly on an automatic property then it would mean "the property is settable but only in the constructor".

But features don't come for free. (Eric Gunnerson expresses it as "Every feature starts with minus 100 points.") To implement read-only automatic properties would have required additional compiler effort to support the readonly modifier on a property (it currently applies only to fields), to generate the appropriate backing field and to transform sets of the property to assignments to the backing field. That's quite a bit of work to support something that the user could do reasonably easily by declaring a readonly backing field and writing a one-line property getter, and that work would have a cost in terms of not implementing other features.

So, quite seriously, the answer is that either the language designers and implementers either never thought of the idea, or -- more likely -- they thought it would be nice to have, but decided there were better places to spend their finite resources. There's no technical constraint that prevents the language designers and implementers providing the feature you suggest: the reasons are more about the economics of software development.


If you want to make a property "read only" as far as functionality is concerned, you do so by only supplying the get method, as you indicated in your post.

public int Width { get { return _width; } } 
public int Height { get { return _height; } } 

The compiler will even reference these as "read only" if you try to write to them.

Having an additional term of readonly for a property would clash with also providing the set method. It seems to be poor syntax to me, i.e. how does the person reading it (or the compiler, for that matter) know what takes precedence: readonly or set?

Furthermore, as was explained in the answer you referenced, readonly applies only to fields and limits writing to those fields to the instantiation of the class. With properties, you can't write to them (I don't think) even within the constructor if they only have a get method.


You can make an automatic property read only by specifying the private access modifier for set like so

public bool Property {get; private set;}

The setter is still defined but it is no longer visible outside the class where the property is defined. As an aside, it is sometimes useful to define the setter as internal so that properties can be easily set from within the same assembly, but not by external callers.


Properties can be read-only, just not automatic properties.

Both get and set are required for automatic properties, and it makes no sense for a read-only property to have a set.

You can define a regular property as a read-only property by just defining the get - however, even if the requirement for both get and set for automatic properties didn't exist - the read-only property couldn't be automatically defined because you have to know the backing field to be able to set it's value internally (i.e. through the constructor).

I suppose there could be a template/macro or something defined in VS to generate the code this, but it couldn't be a part of the language itself.


I think fundamentally the problem is that properties are merely syntactic sugar for a field with optional getter/setter methods. Automatic properties generate the backing field so they require the "setter" or there would be no way to set the value of the backing field. Since properties really map onto methods, not fields, it doesn't make any sense to make them readonly.

Even if allowed, readonly could only apply to automatic properties. For traditional properties, you can put arbitrary code in both the getter and the setter. Even if the setter were able to be invoked only in the constructor of the class, the getter could still mutate the value based on whatever logic you decided to put in it. This would wholly inconsistent with the concept of readonly, thus necessitating different syntax rules and support for automatic/traditional properties. Since there is a mechanism -- using traditional properties with only a getter defined AND a readonly backing field as in the referenced question -- I see no point in mucking up the property syntax and potentially introducing confusion for something with a fairly easy and straightforward implementation using the current language constructs.


If the propert has a private set, then it is readonly from the outside world, i.e:

string _name;
public string Name
{
     get{ return _name; }
     private set { _name = value; }
}

Or, it can be made readonly if it doesnt have the setter at all, i.e.:

string _name;
public string Name
{
     get{ return _name; }
}


In C# 6, auto properties can be readonly https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-6#read-only-auto-properties

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜