首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >对象初始化器中的只读字段

对象初始化器中的只读字段
EN

Stack Overflow用户
提问于 2013-08-22 15:48:32
回答 8查看 9K关注 0票数 18

我想知道为什么不可能做到以下几点:

代码语言:javascript
运行
复制
struct TestStruct
{
    public readonly object TestField;
}

TestStruct ts = new TestStruct {
    /* TestField = "something" // Impossible */
};

对象初始化器难道不能设置字段的值吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2013-08-22 15:50:43

对象初始化器在内部使用一个临时对象,然后将每个值分配给属性。有一个只读字段会打破这一点。

下面是

代码语言:javascript
运行
复制
TestStruct ts = new TestStruct 
{
     TestField = "something";
};

会转化成

代码语言:javascript
运行
复制
TestStruct ts;
var tmp = new TestStruct();
tmp.TestField = "something"; //this is not possible
ts = tmp;

(下面是带有对象初始化器的Jon解释临时对象用法的答案,但使用的是不同的场景)

票数 14
EN

Stack Overflow用户

发布于 2013-08-22 15:50:27

readonly意味着只能在构造函数(或字段初始化器)中设置字段。对象初始化器中指定的属性是在构造函数返回后设置的。那是,

代码语言:javascript
运行
复制
TestStruct ts = new TestStruct {
    TestField = "something"
};

基本上相当于

代码语言:javascript
运行
复制
TestStruct ts = new TestStruct();
ts.TestField = "something";

(在Debug构建中,编译器可能使用一个临时变量,但您了解了这一点。)

票数 13
EN

Stack Overflow用户

发布于 2020-08-10 16:04:40

不管名称如何,C# 9纯Init属性将允许初始化器语法能够设置只读字段

以下是从链接中复制的相关部分。

纯Init属性

下面是一个简单的对象初始化程序示例。

代码语言:javascript
运行
复制
new Person
{
    FirstName = "Scott",
    LastName = "Hunter"
}

现在最大的限制是,要使对象初始化器工作,属性必须是可变的:它们首先调用对象的构造函数(在本例中是默认的、无参数的构造函数),然后分配给属性设置器。

只有属性才能解决这个问题!它们引入了一个init访问器,它是set访问器的一个变体,只能在对象初始化期间调用:

代码语言:javascript
运行
复制
public class Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }
}

有了这个声明,上面的客户端代码仍然是合法的,但是任何后续分配给FirstNameLastName属性都是错误的。

Init访问器和只读字段

因为只有在初始化期间才能调用init访问器,所以允许它们对封闭类的readonly字段进行变异,就像在构造函数中一样。

代码语言:javascript
运行
复制
public class Person
{
    private readonly string firstName;
    private readonly string lastName;
    
    public string FirstName 
    { 
        get => firstName; 
        init => firstName = (value ?? throw new ArgumentNullException(nameof(FirstName)));
    }
    public string LastName 
    { 
        get => lastName; 
        init => lastName = (value ?? throw new ArgumentNullException(nameof(LastName)));
    }
}
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18385248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档