如果我有以下代码:
public class MyClass
{
public string myName { get; private set; }
public string myId { get; set; }
}
为setter创建一个私有编译器生成的变量。我希望只有对象初始化才能访问setter。但是,如何初始设置myName变量?
阅读对象初始化我发现了以下内容:
...它是只读的,而且是 私人领域代表 底层存储有一个 编译器生成的名称,我们 不能在构造函数中使用来分配 它。解决方案是使用[...]对象 初始化
然后,解决方案是使用:
MyClass mc = new MyClass {
myName = "What ever",
myId = "1234"
};
但是这最终会导致编译错误:
属性或索引器 'MyClass.MyClass.myName' 不能在这种情况下使用,因为 设置访问者无法访问
那么,有没有办法使用对象初始化来设置这个值?如果有,做正确的方法是什么?
答案 0 :(得分:13)
没有办法实现这一目标。对象初始化程序仅允许您访问在初始化程序之外可以访问的字段和属性。
您最好的选择是使用显式设置这些属性的构造函数。
答案 1 :(得分:6)
myName 上的私人设置意味着您只能从 MyClass 的成员中初始化(设置)它。例如:
public class MyClass {
public string myName { get; private set; }
public string myId { get; set; }
public static MyClass GetSampleObject() {
MyClass mc = new MyClass
{
myName = "Whatever",
myId = "1234"
};
return mc;
}
}
(我将初始化代码复制并粘贴到 GetSampleObject 方法中)。
但是如果您尝试将其设置在 MyClass 之外,则会出现编译错误,因为私有是私有的。
答案 2 :(得分:5)
如果需要在初始化时设置它们,请考虑将它们作为args传递给构造函数
答案 3 :(得分:1)
我过去也有这个要求以及OR / M的东西。我基本上做的是使用带有支持字段的不动产并检查该属性是否已经设置。如果是这样,请抛出异常。
public string myName
{
get{ return _myName; }
set
{
if( _myName != null && _myName != value )
throw new Exception( "The myName property may only be set once." );
_myName = value;
}
}
private string _myName;
OR / M兼容性的另一个选项也利用了构造函数初始化:
public class MyClass
{
[Obsolete( "For ORM use only!" )]
[EditorBrowsableState( EditorBrowsableState.Never )]
public MyClass(){}
public MyClass( string name ){ myName = name; }
public string myName { get; private set; }
public string myId { get; set; }
}
答案 4 :(得分:0)
自 C#9.0 起,您可以使用init
访问器,该访问器仅在初始化期间即可设置属性值。
声明:
public class MyClass
{
public string myName { get; init; }
public string myId { get; set; }
}
对象初始化将在以下配置下工作:
MyClass mc = new MyClass
{
myName = "What ever",
myId = "1234"
};
查看更多详细信息here。