为什么属性不能只读?

Mat*_*hew 32 c# properties

这个问题在评论想出了这个答案.建议不能使用只读属性作为使用字段而不是属性的潜在原因.

例如:

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; } }
}
Run Code Online (Sandbox Code Playgroud)

但为什么你不能这样做呢?

public int Width { get; readonly set; }
Run Code Online (Sandbox Code Playgroud)

编辑(澄清):您可以在第一个示例中实现此功能.但是为什么你不能用自动实现的属性速记来做同样的事情呢?它也不会那么混乱,因为你不必直接访问构造函数中的字段; 所有访问都将通过该属性.

编辑(更新):从C#6.0开始,支持只读属性!object MyProp { get; }此属性可以设置为inline(object MyProp { get; } = ...)或构造函数,但不能设置其他地方(就像readonly字段一样).

ito*_*son 23

因为语言不允许.

这似乎是一个无聊的答案:毕竟,语言设计者可能已经声明,如果你readonly在自动属性上使用,那么它将意味着"属性是可设置的,但仅在构造函数中".

但功能不是免费的.(Eric Gunnerson将其表示为"每个功能从零点开始.")要实现只读自动属性,需要额外的编译器工作来支持属性上的readonly修饰符(它目前仅适用于字段),以生成适当的支持字段以及sets将属性转换为支持字段的分配.通过声明一个只读后备字段并编写一行属性getter来支持用户可以合理轻松完成的工作,这是相当多的工作,而这项工作在实现其他功能方面会产生成本.

因此,非常严肃地说,答案是语言设计者和实施者要么从未想过这个想法,要么 - 更有可能 - 他们认为这样做会很好,但决定有更好的地方来花费他们有限的资源.没有任何技术限制阻止语言设计者和实现者提供您建议的功能:原因更多的是软件开发的经济性.

  • 是后者.自C#3以来,这一直在列表中.我们很乐意这样做,但它从未有过足够高的优先级.我们提出了几百种关于新语言功能的想法,我们只在每个版本中做了几个. (6认同)
  • @ ken2k:你可能会问,但你不会得到一个好的答案.需要预测未来的问题是StackOverflow的难题.概率不为零,但你已经知道了. (2认同)

Ben*_*ack 16

如果您想在功能方面将属性设置为"只读",则只需get按照帖子中的说明提供方法即可.

public int Width { get { return _width; } } 
public int Height { get { return _height; } } 
Run Code Online (Sandbox Code Playgroud)

如果您尝试写入它们,编译器甚至会将它们称为"只读".

拥有一个readonly属性的附加项将与提供该set方法发生冲突.它对我来说似乎是不好的语法,即阅读它的人(或编译器,如何)知道什么是优先的:readonly或者set

此外,正如您引用的答案中所解释的那样,readonly仅适用于写入这些字段的字段和限制到类的实例化.对于属性,即使在构造函数中,如果它们只有一个get方法,也不能写入它们(我不认为).

  • 你是对的,它提供了相同的功能.这就是为什么它被列为一个例子.我的问题是:为什么你不能用自动实现的属性速记来做同样的事情?它也不会那么混乱,因为你不必直接访问构造函数中的字段; 所有访问都将通过该属性. (2认同)

Cri*_*urf 9

您可以通过为set设置私有访问修饰符来使自动属性只读

public bool Property {get; private set;}
Run Code Online (Sandbox Code Playgroud)

仍然定义了setter,但在定义属性的类之外它不再可见.顺便说一句,将setter定义为internal是有用的,这样可以在同一个程序集中轻松设置属性,但不能由外部调用者设置.

  • 这与`readonly`没有相同的语义. (9认同)
  • 它不会阻止类中的值从构造函数外部进行修改. (2认同)