Automated 属性 with getter only, can be set, 为什么?
Automated property with getter only, can be set, why?
我创建了一个自动 属性:
public int Foo { get; }
这只是 getter。
但是当我构建构造函数时,我可以更改值:
public MyClass(string name)
{
Foo = 5;
}
为什么这是可能的,即使这是 get-only?
这是 a new feature in C#6,它允许您创建 read-only 属性并从构造函数(或在声明它们时内联)初始化它们的值。
如果您尝试在构造函数之外更改此 属性 的值,则会出现编译错误。
从某种意义上说,它是 read-only,一旦你初始化它的值(内联或在构造函数中),你就不能改变它的值。
Auto 属性 功能已在 C# 3.0 版本中添加到语言中。它允许您定义一个 属性 没有任何支持字段,但是您仍然需要使用构造函数将这些自动属性初始化为 non-default 值。 C# 6.0 引入了一个名为 auto 属性 initializer 的新功能,它允许您在没有构造函数的情况下初始化这些属性,如下所示:
Previously, a constructor is required if you want to create objects
using an auto-property and initialize an auto-property to a
non-default value like below:
public class MyClass
{
public int Foo { get; }
public Foo(int foo)
{
Foo = foo;
}
}
Now in C# 6.0, the ability to use an initializer with the auto-property
means no explicit constructor code is required.
public string Foo { get; } = "SomeString";
public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };
如果无法从构造函数(或 auto-property 初始化器)初始化 read-only 属性,那么它将毫无用处,因为它总是 return 其类型的默认值(数字为 0,引用类型为 null)。适用于所有 C# 版本中的 readonly 字段的相同语义。
要定义一个真正的 getter-only 属性(不能从构造函数初始化),您需要在定义中指定它 return 的内容:
public int Foo { get { return 5; } }
或者,在 C# 6 中更简洁:
public int Foo => 5;
这是一个新的 C# 6 功能,"Getter-only auto-properties",也称为 "Auto-Property Initializers for Read-Only Properties",如本 MSDN magazine article 'C# : The New and Improved C# 6.0' by Mark Michaelis and in the C# 6.0 draft Language Specification 中所述。
read-only 字段的 setter 只能在构造函数中访问,在所有其他情况下,该字段仍然是只读的并且行为与以前一样。
这是一种方便的语法,可以减少您需要键入的代码量,并且无需显式声明私有模块级变量来保存值。
这个特性被认为很重要,因为在 C#3 中引入了 Auto-Implemented 属性,可变属性(带有 getter 和 setter 的属性)变得更快编写而不是不可变属性(那些只有 getter 的属性),这意味着人们很想使用可变属性以避免必须为 read-only 属性通常需要的支持字段键入代码。在 relevant section of the Microsoft C# Programming Guide 中有更多关于 Auto-Implemented 属性的讨论。
This blog post, '#1,207 – C# 6.0 – Auto-Property Initializers for Read-Only Properties' by Sean Sexton 有很好的解释和例子如下:
Prior to C# 6.0, if you wanted a read-only (immutable) property, you’d
typically use a read-only backing field that is initialized in the
constructor, as shown below.
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;
}
}
In C# 6.0, you can use auto-implemented properties to implement a
read-only property. You do this by using an auto-property
initializer. The result is much cleaner than the above example, where
we had to explicitly declare a backing field.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
public DateTime DogCreationTime { get; } = DateTime.Now;
public Dog(string name)
{
Name = name;
}
}
也可以在the dotnet Roslyn repo on GitHub中找到更多详细信息:
Auto-properties can now be declared without a setter.
The backing field of a getter-only auto-property is implicitly
declared as readonly (though this matters only for reflection
purposes). It can be initialized through an initializer on the
property as in the example above. Also, a getter-only property can be
assigned to in the declaring type’s constructor body, which causes the
value to be assigned directly to the underlying field:
This is about expressing types more concisely, but note that it also
removes an important difference in the language between mutable and
immutable types: auto-properties were a shorthand available only if
you were willing to make your class mutable, and so the temptation to
default to that was great. Now, with getter-only auto-properties, the
playing field has been leveled between mutable and immutable.
和 C# 6.0 draft Language Specification (NB: The language specification is final as far as Microsoft are concerned, but it is yet to be approved as a EMCA/ISO standard,因此 'draft'):
Automatically implemented properties
An automatically implemented property (or auto-property for short), is
a non-abstract non-extern property with semicolon-only accessor
bodies. Auto-properties must have a get accessor and can optionally
have a set accessor.
When a property is specified as an automatically implemented property,
a hidden backing field is automatically available for the property,
and the accessors are implemented to read from and write to that
backing field. If the auto-property has no set accessor, the backing
field is considered readonly (Readonly fields). Just like a readonly
field, a getter-only auto-property can also be assigned to in the body
of a constructor of the enclosing class. Such an assignment assigns
directly to the readonly backing field of the property.
An auto-property may optionally have a property_initializer, which is
applied directly to the backing field as a variable_initializer
(Variable initializers).
声明为 readonly
的变量可以在构造函数中编写,但在支持该属性的语言中,不能在构造函数 return 之后修改。该限定符是作为一种语言功能提供的,因为对于其值会根据构造函数参数而变化(意味着它们不能在构造函数启动之前初始化)但在构造函数之后不必更改的字段通常是必需的 return ,但它仅可用于作为字段公开的变量。 readonly
限定字段的语义在许多情况下对于 public 成员来说是完美的,除了 类 公开成员——甚至是不可变的成员——作为属性而不是公开成员通常更好字段。
正如 read-write auto-properties 的存在允许 类 像普通字段一样容易地公开可变属性,read-only auto-properties 的存在允许 类 像 readonly
限定的字段一样容易地公开不可变属性。正如 readonly
限定的字段可以写在构造函数中一样,get-only 属性也是如此。
“只读自动实现属性”
首先我想澄清的是 属性 喜欢
public string FirstName { get; }
被称为“只读自动实现的属性”
要验证这一点,您可以 运行 并使用 Visual Studio 检查上面的代码。如果将语言版本从 C#6.0 更改为 C#5.0,则编译器将抛出以下异常
功能 'readonly automatically implemented properties' 在 C# 5 中不可用。请使用语言版本 6 或更高版本。
要更改 C# 语言版本请访问 here
现在我来回答你的第二个问题
“这只是 getter。但是当我构建构造函数时,我可以更改值”
微软在只读逻辑上引入了“readonly automatically implemented properties”。正如我们所知,关键字“readonly”在 C#1.0 中可用。我们在字段上使用“readonly”关键字作为修饰符,该字段可以 2 种方式分配 在声明时 或 在同一个构造函数中 class.
同样,“只读自动实现的属性”的值可以通过两种方式分配
Way1(申报时):
public string FirstName { get; } = "Banketeshvar";
Way2(在同一个构造函数中class)
Person()
{
FirstName = "Banketeshvar";
}
纯只读属性
如果您正在寻找纯粹的只读 属性 那么就选择这个
public string FullName => "Manish Sharma";
现在您不能从构造函数中分配“FullName”属性 的值。
如果您尝试这样做,它将抛出以下异常
“属性 或索引器 'Person.FullName' 无法分配给 -- 它是只读的”
我创建了一个自动 属性:
public int Foo { get; }
这只是 getter。 但是当我构建构造函数时,我可以更改值:
public MyClass(string name)
{
Foo = 5;
}
为什么这是可能的,即使这是 get-only?
这是 a new feature in C#6,它允许您创建 read-only 属性并从构造函数(或在声明它们时内联)初始化它们的值。
如果您尝试在构造函数之外更改此 属性 的值,则会出现编译错误。
从某种意义上说,它是 read-only,一旦你初始化它的值(内联或在构造函数中),你就不能改变它的值。
Auto 属性 功能已在 C# 3.0 版本中添加到语言中。它允许您定义一个 属性 没有任何支持字段,但是您仍然需要使用构造函数将这些自动属性初始化为 non-default 值。 C# 6.0 引入了一个名为 auto 属性 initializer 的新功能,它允许您在没有构造函数的情况下初始化这些属性,如下所示:
Previously, a constructor is required if you want to create objects using an auto-property and initialize an auto-property to a non-default value like below:
public class MyClass
{
public int Foo { get; }
public Foo(int foo)
{
Foo = foo;
}
}
Now in C# 6.0, the ability to use an initializer with the auto-property means no explicit constructor code is required.
public string Foo { get; } = "SomeString";
public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };
如果无法从构造函数(或 auto-property 初始化器)初始化 read-only 属性,那么它将毫无用处,因为它总是 return 其类型的默认值(数字为 0,引用类型为 null)。适用于所有 C# 版本中的 readonly 字段的相同语义。
要定义一个真正的 getter-only 属性(不能从构造函数初始化),您需要在定义中指定它 return 的内容:
public int Foo { get { return 5; } }
或者,在 C# 6 中更简洁:
public int Foo => 5;
这是一个新的 C# 6 功能,"Getter-only auto-properties",也称为 "Auto-Property Initializers for Read-Only Properties",如本 MSDN magazine article 'C# : The New and Improved C# 6.0' by Mark Michaelis and in the C# 6.0 draft Language Specification 中所述。
read-only 字段的 setter 只能在构造函数中访问,在所有其他情况下,该字段仍然是只读的并且行为与以前一样。
这是一种方便的语法,可以减少您需要键入的代码量,并且无需显式声明私有模块级变量来保存值。
这个特性被认为很重要,因为在 C#3 中引入了 Auto-Implemented 属性,可变属性(带有 getter 和 setter 的属性)变得更快编写而不是不可变属性(那些只有 getter 的属性),这意味着人们很想使用可变属性以避免必须为 read-only 属性通常需要的支持字段键入代码。在 relevant section of the Microsoft C# Programming Guide 中有更多关于 Auto-Implemented 属性的讨论。
This blog post, '#1,207 – C# 6.0 – Auto-Property Initializers for Read-Only Properties' by Sean Sexton 有很好的解释和例子如下:
Prior to C# 6.0, if you wanted a read-only (immutable) property, you’d typically use a read-only backing field that is initialized in the constructor, as shown below.
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; } }
In C# 6.0, you can use auto-implemented properties to implement a read-only property. You do this by using an auto-property initializer. The result is much cleaner than the above example, where we had to explicitly declare a backing field.
public class Dog { public string Name { get; set; } // DogCreationTime is immutable public DateTime DogCreationTime { get; } = DateTime.Now; public Dog(string name) { Name = name; } }
也可以在the dotnet Roslyn repo on GitHub中找到更多详细信息:
Auto-properties can now be declared without a setter.
The backing field of a getter-only auto-property is implicitly declared as readonly (though this matters only for reflection purposes). It can be initialized through an initializer on the property as in the example above. Also, a getter-only property can be assigned to in the declaring type’s constructor body, which causes the value to be assigned directly to the underlying field:
This is about expressing types more concisely, but note that it also removes an important difference in the language between mutable and immutable types: auto-properties were a shorthand available only if you were willing to make your class mutable, and so the temptation to default to that was great. Now, with getter-only auto-properties, the playing field has been leveled between mutable and immutable.
和 C# 6.0 draft Language Specification (NB: The language specification is final as far as Microsoft are concerned, but it is yet to be approved as a EMCA/ISO standard,因此 'draft'):
Automatically implemented properties
An automatically implemented property (or auto-property for short), is a non-abstract non-extern property with semicolon-only accessor bodies. Auto-properties must have a get accessor and can optionally have a set accessor.
When a property is specified as an automatically implemented property, a hidden backing field is automatically available for the property, and the accessors are implemented to read from and write to that backing field. If the auto-property has no set accessor, the backing field is considered readonly (Readonly fields). Just like a readonly field, a getter-only auto-property can also be assigned to in the body of a constructor of the enclosing class. Such an assignment assigns directly to the readonly backing field of the property.
An auto-property may optionally have a property_initializer, which is applied directly to the backing field as a variable_initializer (Variable initializers).
声明为 readonly
的变量可以在构造函数中编写,但在支持该属性的语言中,不能在构造函数 return 之后修改。该限定符是作为一种语言功能提供的,因为对于其值会根据构造函数参数而变化(意味着它们不能在构造函数启动之前初始化)但在构造函数之后不必更改的字段通常是必需的 return ,但它仅可用于作为字段公开的变量。 readonly
限定字段的语义在许多情况下对于 public 成员来说是完美的,除了 类 公开成员——甚至是不可变的成员——作为属性而不是公开成员通常更好字段。
正如 read-write auto-properties 的存在允许 类 像普通字段一样容易地公开可变属性,read-only auto-properties 的存在允许 类 像 readonly
限定的字段一样容易地公开不可变属性。正如 readonly
限定的字段可以写在构造函数中一样,get-only 属性也是如此。
“只读自动实现属性”
首先我想澄清的是 属性 喜欢
public string FirstName { get; }
被称为“只读自动实现的属性”
要验证这一点,您可以 运行 并使用 Visual Studio 检查上面的代码。如果将语言版本从 C#6.0 更改为 C#5.0,则编译器将抛出以下异常 功能 'readonly automatically implemented properties' 在 C# 5 中不可用。请使用语言版本 6 或更高版本。
要更改 C# 语言版本请访问 here
现在我来回答你的第二个问题
“这只是 getter。但是当我构建构造函数时,我可以更改值”
微软在只读逻辑上引入了“readonly automatically implemented properties”。正如我们所知,关键字“readonly”在 C#1.0 中可用。我们在字段上使用“readonly”关键字作为修饰符,该字段可以 2 种方式分配 在声明时 或 在同一个构造函数中 class.
同样,“只读自动实现的属性”的值可以通过两种方式分配
Way1(申报时):
public string FirstName { get; } = "Banketeshvar";
Way2(在同一个构造函数中class)
Person()
{
FirstName = "Banketeshvar";
}
纯只读属性
如果您正在寻找纯粹的只读 属性 那么就选择这个
public string FullName => "Manish Sharma";
现在您不能从构造函数中分配“FullName”属性 的值。 如果您尝试这样做,它将抛出以下异常
“属性 或索引器 'Person.FullName' 无法分配给 -- 它是只读的”