我想知道为什么不可能做到以下几点:
struct TestStruct
{
public readonly object TestField;
}
TestStruct ts = new TestStruct {
/* TestField = "something" // Impossible */
};对象初始化器难道不能设置字段的值吗?
发布于 2013-08-22 15:50:43
对象初始化器在内部使用一个临时对象,然后将每个值分配给属性。有一个只读字段会打破这一点。
下面是
TestStruct ts = new TestStruct
{
TestField = "something";
};会转化成
TestStruct ts;
var tmp = new TestStruct();
tmp.TestField = "something"; //this is not possible
ts = tmp;(下面是带有对象初始化器的Jon解释临时对象用法的答案,但使用的是不同的场景)
发布于 2013-08-22 15:50:27
readonly意味着只能在构造函数(或字段初始化器)中设置字段。对象初始化器中指定的属性是在构造函数返回后设置的。那是,
TestStruct ts = new TestStruct {
TestField = "something"
};基本上相当于
TestStruct ts = new TestStruct();
ts.TestField = "something";(在Debug构建中,编译器可能使用一个临时变量,但您了解了这一点。)
发布于 2020-08-10 16:04:40
不管名称如何,C# 9纯Init属性将允许初始化器语法能够设置只读字段。
以下是从链接中复制的相关部分。
下面是一个简单的对象初始化程序示例。
new Person
{
FirstName = "Scott",
LastName = "Hunter"
}现在最大的限制是,要使对象初始化器工作,属性必须是可变的:它们首先调用对象的构造函数(在本例中是默认的、无参数的构造函数),然后分配给属性设置器。
只有属性才能解决这个问题!它们引入了一个init访问器,它是set访问器的一个变体,只能在对象初始化期间调用:
public class Person
{
public string FirstName { get; init; }
public string LastName { get; init; }
}有了这个声明,上面的客户端代码仍然是合法的,但是任何后续分配给FirstName和LastName属性都是错误的。
因为只有在初始化期间才能调用init访问器,所以允许它们对封闭类的readonly字段进行变异,就像在构造函数中一样。
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)));
}
}https://stackoverflow.com/questions/18385248
复制相似问题