是否可以在同一属性上使用公共初始化访问器和私有设置器?
目前我收到错误CS1007“属性访问器已定义”。
public record Stuff
{
public int MyProperty { get; init; private set; } // Error
public void SetMyProperty(int value) => MyProperty = value;
}
var stuff = new Stuff
{
MyProperty = 3, // Using the init accessor
};
stuff.SetMyProperty(4); // Using the private setter (indirectly)
我最好的猜测是使用私有成员变量,该变量的属性带有
get
和 init
访问器(不是自动实现的)和 setter 成员函数。可以更轻松地完成吗?
与指定构造函数来初始化值类似,您可以使用私有支持字段,这样您仍然可以利用 init 逻辑并允许在没有特定构造函数的情况下进行初始化
public record Stuff
{
private int _myProperty;
public int MyProperty { get => _myProperty; init => _myProperty = value; }
public void SetMyProperty(int value) => _myProperty = value;
}
var stuff = new Stuff
{
MyProperty = 3 // Using the init accessor
};
stuff.SetMyProperty(4); // Using the private setter (indirectly)
不,你不能。添加 init 关键字是为了尝试在对象上创建不可变属性。
所以如果你有记录:
public record Stuff
{
public int MyProperty { get; init; } // This can not be changed after initialization
}
MyProperty
只能在记录初始化期间设置。
如果您希望属性是可变的,那么您可以使用
set
访问器 而不是 init
的。
public record Stuff
{
public int MyProperty { get; set; } // This can
}
作为@Jerry的答案,你不能同时使用这两个设置器。这与记录/对象的可变性有关。
如果你想要
private set
和一些初始化逻辑,我使用的方式是构造函数:
public record Stuff
{
public Stuff(int myProperty)
{
MyProperty = myProperty;
}
public int MyProperty { get; private set; }
public void SetMyProperty(int value) => MyProperty = value;
}
var stuff = new Stuff(3);
stuff.SetMyProperty(4);
这一切都与域要求有关。
Stuff.MyProperty
需要公开修改吗?等等..
如果您有一条包含多个属性的记录,并且希望仅更改其中几个属性的设置器的可访问性,您可以使用以下语法:
public sealed record Stuff(int MyProperty, string ImutableProperty, DateTimeOffset AnotherProperty)
{
public int MyProperty { get; private set; } = MyProperty;
public DateTimeOffset AnotherProperty { get; set; } = AnotherProperty;
public void SetMyProperty(int value) => MyProperty = value;
}
在此代码中,
MyProperty
有一个私有setter,因此只能在类构造函数中设置。 AnotherProperty
有一个公共设置器,允许从外部代码设置它。此外,构造函数用于在创建记录实例时设置属性的初始值。