Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';属性不能是只读的吗?_C#_Properties - Fatal编程技术网

C# 为什么可以';属性不能是只读的吗?

C# 为什么可以';属性不能是只读的吗?,c#,properties,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

这个问题是在他的评论中提出来的。无法拥有只读属性被认为是使用字段而不是属性的潜在原因

例如:

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; } }
}
但你为什么不能这么做呢

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


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

如果要使属性在功能方面为“只读”,只需提供
get
方法即可,正如你在帖子中指出的那样

public int Width { get { return _width; } } 
public int Height { get { return _height; } } 
如果您试图对它们进行写入,编译器甚至会将它们引用为“只读”

为属性增加一个
readonly
术语将与同时提供
set
方法相冲突。对我来说,它的语法似乎很糟糕,也就是说,阅读它的人(或编译器)如何知道什么是优先的:
readonly
set

此外,正如您在引用的答案中所解释的,
readonly
仅适用于字段,并将对这些字段的写入限制为类的实例化。对于属性,如果它们只有
get
方法,则即使在构造函数中也无法写入它们(我不认为)。属性可以是只读的,而不是自动属性

自动属性需要
get
set
,只读属性设置
是没有意义的

只需定义
get
,即可将常规属性定义为只读属性,即使自动属性的
get
set
要求不存在,也无法自动定义只读属性,因为您必须知道支持字段才能在内部(即通过构造函数)设置其值


我想可能会有一个模板/宏或VS中定义的东西来生成此代码,但它不能成为语言本身的一部分

通过为set like so指定私有访问修饰符,可以使自动属性只读

public bool Property {get; private set;}

setter仍在定义中,但在定义属性的类之外它不再可见。另一方面,有时将setter定义为内部是很有用的,这样可以从同一程序集中轻松地设置属性,但外部调用方不能设置属性。

,因为该语言不允许这样做

这似乎是一个轻率的回答:毕竟,语言设计者可以声明,如果在自动属性上使用
readonly
,那么这意味着“该属性是可设置的,但仅在构造函数中”

但功能不是免费提供的。(Eric Gunnerson将其表述为“每个功能都以开始。”)要实现只读自动属性,需要额外的编译器工作来支持属性上的只读修饰符(它目前仅适用于字段),生成适当的支持字段,并将属性的
转换为支持字段的赋值。要支持用户可以通过声明一个只读支持字段和编写一行属性getter轻松完成的事情,需要做大量的工作,而这项工作的代价是不实现其他功能


因此,相当严肃地说,答案是要么语言设计者和实现者从未想过这个想法,要么——更可能的是——他们认为拥有这个想法会很好,但决定有更好的地方来使用他们有限的资源。没有任何技术约束阻止语言设计者和实现者提供您建议的功能:原因更多的是关于软件开发的经济性。

我认为从根本上说,问题在于属性只是具有可选getter/setter方法的字段的语法糖。自动属性生成支持字段,因此它们需要“setter”,否则将无法设置支持字段的值。由于属性实际上映射到方法,而不是字段,因此将它们设为只读是没有任何意义的


即使允许,只读也只能应用于自动属性。对于传统属性,可以在getter和setter中放置任意代码。即使setter只能在类的构造函数中调用,getter仍然可以根据您决定放入的任何逻辑来修改值。这完全不符合只读的概念,因此需要不同的语法规则和对自动/传统属性的支持。因为有一种机制——使用传统的属性,只定义了一个getter和一个readonly backing字段,就像前面提到的问题一样——我认为没有必要弄乱属性语法,也没有必要为使用当前语言的相当简单直接的实现带来混淆构造。

如果属性有一个私有集,则它是外部世界只读的,即:

string _name;
public string Name
{
     get{ return _name; }
     private set { _name = value; }
}
或者,如果它根本没有设置器,则可以将其设置为只读,即:

string _name;
public string Name
{
     get{ return _name; }
}
在C#6中,自动属性可以是只读的

您是对的,它提供了相同的功能。这就是为什么它被列为一个例子。我的问题是:为什么不能使用自动实现的属性速记来做同样的事情