自动属性只有吸气剂,可以设置,为什么?

我创build了一个自动化属性:

public int Foo { get; } 

这只是吸气剂。 但是当我构build一个构造函数时,我可以改变它的值:

 public MyClass(string name) { Foo = 5; } 

为什么这是可能的,即使这是只能得到的?

这是一个新的C#6function,即Getter-only自动属性,也被称为“只读属性的自动属性初始化程序”,正如在MSDN杂志文章“C#:The New and Improved C#6.0”中所讨论的Michaelis和C#6.0语言规范草案 。

只读字段的setter只能在构造函数中访问,在所有其他场景下,字段仍然是只读的,并且像以前一样运行。

这是一种方便的语法,用于减less需要键入的代码量,并删除显式声明私有模块级variables来保存值的需要。

这个特性被认为是重要的,因为在C#3中引入了自动实现的属性,可变属性(带有getter和setter的属性)比不可变属性(只有getter的那些属性)变得更快,试图使用可变属性来避免必须键入通常只读属性所需的支持字段的代码。 Microsoft C#编程指南的相关章节中有关于自动执行属性的更多讨论。

本篇博文“#1,207 – C#6.0 – 只读属性的自动属性初始化器”作者:Sean Sexton有一个很好的解释和例子如下:

在C#6.0之前,如果你想要一个只读(immutable)属性,你通常会使用在构造函数中初始化的只读后台字段,如下所示。

 public class Dog { public string Name { get; set; } // DogCreationTime is immutable private readonly DateTime creTime; public DateTime DogCreationTime { get { return creTime; } } public Dog(string name) { Name = name; creTime = DateTime.Now; } } 

在C#6.0中,可以使用自动实现的属性来实现只读属性。 您可以通过使用自动属性初始值设定项来执行此操作。 结果比上面的例子要干净得多,我们必须明确声明一个后台字段。

 public class Dog { public string Name { get; set; } // DogCreationTime is immutable public DateTime DogCreationTime { get; } = DateTime.Now; public Dog(string name) { Name = name; } } 

更多的细节也可以在GitHub上的dotnet Roslyn repo中find :

自动属性现在可以在没有setter的情况下声明。

只有getter的auto属性的后台字段被隐式声明为只读(尽pipe这只是出于reflection的目的)。 它可以通过属性的初始化程序初始化,如上例所示。 另外,可以在声明types的构造函数体中为getter-only属性赋值,这会导致将值直接分配给基础字段:

这是关于更简洁地expressiontypes,但是请注意,它也消除了可变types与不可变types之间语言的重要区别:只有当您愿意让您的类变为可变时,自动属性才是可用的简写forms,所以诱惑默认这很好。 现在,只有getter-only自动属性,运动场已经在可变和不可变之间变平。

并在C#6.0草案语言规范 :

自动实现的属性

一个自动实现的属性(简称自动属性),是一个非抽象非extern属性,仅含分号访问器主体。 自动属性必须有一个get访问器,可以有一个set访问器。

当一个属性被指定为一个自动实现的属性时,一个隐藏的后台字段对于该属性是自动可用的,访问器被实现为读取和写入该后台字段。 如果auto属性没有set访问器,则后台字段被认为是只读的(Readonly字段)。 就像readonly字段,也可以在封闭类的构造函数的主体中分配一个getter-only自动属性。 这种分配直接分配给属性的只读后台字段。

一个自动属性可以有一个property_initializer,作为variable_initializer(variables初始值设定项)直接应用于后台字段。

这是C#6中的一个新特性,它允许您创build只读属性,并从构造函数中初始化它们的值(或者在声明它们时内联)。

如果你试图在构造函数之外改变这个属性的值,它会给你一个编译错误。

它是只读的,一旦你初始化它的值(内联或内部的构造函数),你不能改变它的值。

如果无法从构造函数(或自动属性初始值设定项)初始化只读属性,那么它将是无用的,因为它总是返回其types的默认值(0表示数字,null表示引用types)。 所有C#版本中的只读字段都使用相同的语义。

要定义一个真正的getter-only属性(不能从构造函数初始化),您需要指定它作为定义的一部分返回的内容:

 public int Foo { get { return 5; } } 

或者,在C#6中更简洁:

 public int Foo => 5; 

在C#3.0发行版中,将自动属性function添加到该语言中。 它允许您定义一个没有任何后台字段的属性,但是您仍然需要使用构造函数将这些自动属性初始化为非默认值。 C#6.0引入了一个名为auto property initializer的新特性,它允许你在没有像下面这样的构造函数的情况下初始化这些属性:

以前,如果要使用自动属性创build对象并将自动属性初始化为非默认值(如下所示),则需要构造函数:

 public class MyClass { public int Foo { get; } public Foo(int foo) { Foo = foo; } } 

现在在C#6.0中,使用具有auto属性的初始值设定项的能力意味着不需要显式的构造函数代码。

 public string Foo { get; } = "SomeString"; public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" }; 

你可以在这里find更多的信息

“只读自动实现属性”

首先我想澄清一下这个属性

 public string FirstName { get; } 

被称为“只读自动实现的属性”

要validation这一点,你可以运行和检查上面的代码与Visual Studio。 如果将语言版本从C#6.0更改为C#5.0,则编译器将引发以下exceptionfunction“只读自动实现的属性”在C#5中不可用。请使用语言版本6或更高版本。

改变C#语言版本访问这里

现在我来谈谈你的第二个问题

“这只是吸气剂。 但是当我构build一个构造函数时,我可以将值“

微软在只读逻辑上引入了“只读自动实现的属性”。 我们知道关键字“只读”可以从C#1.0中获得。 我们在字段上使用“只读”关键字作为修饰符,并且可以在声明时在同一个类的构造函数中两种方式分配该字段

以同样的方式,“只读自动实现的属性”的值可以以两种方式分配

方式1(申报时):

 public string FirstName { get; } = "Banketeshvar"; 

Way2(在同一个类的构造函数中)

 Person() { FirstName = "Banketeshvar"; } 

纯粹的只读属性

如果你正在寻找纯粹的Readonly财产然后去这个

 public string FullName => "Manish Sharma"; 

现在你不能从构造函数赋值“FullName”。 如果你试图这样做,它会抛出以下例外

“属性或索引器”Person.FullName“不能被分配给 – 它是只读的”

声明为readonly的variables可以写在构造函数中,但是在使用该属性的语言中,在构造函数返回后不能修改。 该限定符是作为一种语言function提供的,因为对于其值根据构造函数参数而变化的字段(意味着它们在构造函数启动之前不能被初始化)通常是必要的,但是在构造函数返回之后将不必改变,只能用于暴露为字段的variables。 readonly -qualified字段的语义在许多情况下对于公共成员来说是完美的,除了类将类成员(甚至不可变的成员)暴露为属性而不是字段通常更好。

正如读写自动属性允许类像普通字段一样容易地暴露可变属性,存在只读自动属性以允许类像readonly属性字段一样容易地显示不可变属性。 就像readonly -qualified字段可以写在构造函数中一样,只有get-only属性也是如此。