C# 对属性的字段或属性进行赋值时会发生什么情况
假设您拥有如下属性:C# 对属性的字段或属性进行赋值时会发生什么情况,c#,properties,get,set,C#,Properties,Get,Set,假设您拥有如下属性: Person person1; public Person Captin{ get{ return person1; } set{ person1 = value; } } public void SomeFunction(){ Captin.name = "Hook" } 在本例中,如果在属性上设置名称,我们知道Hook的新名称将应用于person1的基础值。如果我们的实施有点不同,那该怎么办
Person person1;
public Person Captin{
get{
return person1;
}
set{
person1 = value;
}
}
public void SomeFunction(){
Captin.name = "Hook"
}
在本例中,如果在属性上设置名称,我们知道Hook的新名称将应用于person1的基础值。如果我们的实施有点不同,那该怎么办呢
public Person Captin{
get{
return ReadCaptinFromDisk();
}
set{
WriteCaptinToDisk(value);
}
}
public void SomeFunction(){
Captin.name = "Hook"
}
在这种情况下,为了正确设置基础值,我们需要调用Captin的set代码,作为Captin.name赋值的一部分
我想知道参数集代码是否会在字段赋值时调用集合,或者在属性引用时调用方法。特别是在这种情况下,需要将值传播到磁盘(等)。每次访问属性Captin时,它都会从磁盘读取。但是,如果更改属性“name”,它将不会写入磁盘。只有在执行以下操作时,它才会写入磁盘
public void SomeFunction() {
Person p = Captin;
p.name = "Hook";
Captin = p;
}
每次访问属性Captin时,它都将从磁盘读取。但是,如果更改属性“name”,它将不会写入磁盘。只有在执行以下操作时,它才会写入磁盘
public void SomeFunction() {
Person p = Captin;
p.name = "Hook";
Captin = p;
}
正如@Joe所指出的,它不会写入磁盘。我只是想补充一点,这是因为您只使用getter,而不是setter@乔的例子使用了这两种方法
在我看来,这不仅是对getter的一种非常糟糕的使用,而且违反了关注点的分离。您应该有一个处理持久化数据的数据层。此逻辑不应在您的业务对象中。正如@Joe所指出的,它不会写入磁盘。我只是想补充一点,这是因为您只使用getter,而不是setter@乔的例子使用了这两种方法
在我看来,这不仅是对getter的一种非常糟糕的使用,而且违反了关注点的分离。您应该有一个处理持久化数据的数据层。此逻辑不应出现在您的业务对象中。只有当有人实际直接分配给属性时,才会调用该属性的setter 至于您的代码是否正常:这是一个文档问题 无论何时,当你有一个属性返回一些可变的东西时,你应该指出它的突变是否会起作用。您是返回“真实”数据的副本,还是真实数据本身?当属性(或普通方法)返回某种集合时,经常会出现这种情况—它是可变的?如果我改变它会发生什么 如果您记录了您的属性,说明返回的数据只是一个副本,并且更改不会在任何地方反映出来,这很好。如果你让它模棱两可,那你就会遇到问题
不变性消除了这些顾虑,当然…只有在有人实际直接分配属性时才会调用属性的setter 至于您的代码是否正常:这是一个文档问题 无论何时,当你有一个属性返回一些可变的东西时,你应该指出它的突变是否会起作用。您是返回“真实”数据的副本,还是真实数据本身?当属性(或普通方法)返回某种集合时,经常会出现这种情况—它是可变的?如果我改变它会发生什么 如果您记录了您的属性,说明返回的数据只是一个副本,并且更改不会在任何地方反映出来,这很好。如果你让它模棱两可,那你就会遇到问题
不变性消除了这些顾虑,当然…类类型变量、参数、字段、返回值或其他此类存储位置应被视为包含“对象id”。如果某个对象
Foo
具有一个名为Bar
的属性,该属性属于某个类类型,由字段\u Bar
支持,并且\u Bar
持有“object id#24601”,则语句Foo.Bar.Text=“George”
将调用对象#24601上的文本设置器,其值为“George”。请注意,此语句不会修改对象Foo
本身(其字段\u-Bar
将在语句执行前保留“object id#24601”,执行后仍保留该字段);然而,它很可能会影响对象24601
结构类型的存储位置应被视为包含其所有字段(公共和私有)的内容。如果Foo.Boz
是Rectangle
(结构)类型的属性和支持字段\u-Boz
,访问Foo.Boz
将创建一个新的Rectangle
类型的临时实例,其所有字段都将从Foo.\u-Boz
的字段复制。尝试读取Foo.Boz.X
会将\u Boz
的所有字段复制到一个临时实例,然后访问该实例的字段X
请注意,一些非常古老和邪恶的C#编译器会解释类似Foo.Boz.X=5的代码代码>作为<代码>矩形温度;温度X=5代码>,丢弃temp的结果值,但不发出任何警告。这样的编译器行为导致一些人声明结构应该是“不可变的”,以确保这样的代码将生成编译器错误,而不是产生虚假的行为。不幸的是,这种信念一直持续到今天,尽管任何一个体面的编译器都会禁止这样的代码,即使X
是一个可变字段
请注意,更新可变结构类型属性的正确惯用方法是:
Rectangle temp = MyListOFRectangles[5];
temp.X = 5;
MyListOFRectangles[5] = temp;
矩形温度=MyListOFRectangles[5];
温度X=5;
MyListOFRectangles[5]=温度;
如果已知Rectangle
有一个名为X
的公共整数字段,并且MyListOfRectangles
是一个列表
,则不需要知道Rectangle
的任何其他属性、构造函数等。要知道上述代码将更改MyListOfRectangles[5].X
但不影响MyListFrectangles[5]
的任何其他属性,也不影响MyListFrectangles[4]
的任何属性。漂亮、清晰、简单。暴露的字段结构允许piec