属性 - 按值还是参考?
我有以下公共属性,它公开了 Arraylist:
public ArrayList SpillageRiskDescriptions
{
get
{
return _SpillageRiskDescriptions;
}
set
{
_SpillageRiskDescriptions = value;
}
}
在其他地方,我调用
SpillageRiskDescriptions.Add("VENTILATE AREA");
SpillageRiskDescriptions.Add("DO NOT ALLOW SPILLAGE TO ENTER MAINS");
这些似乎将元素添加到私有 ArrayList _SpillageRiskDescriptions(通过该属性),而我本来预计这会引起问题。因此,我认为属性返回对原始变量的引用而不是通过值传递它是否正确?这是因为 ArrayList 是引用类型吗? int
也会发生同样的情况吗(例如?)
I've got the following public property which exposes an Arraylist
:
public ArrayList SpillageRiskDescriptions
{
get
{
return _SpillageRiskDescriptions;
}
set
{
_SpillageRiskDescriptions = value;
}
}
Elsewhere I'm calling
SpillageRiskDescriptions.Add("VENTILATE AREA");
SpillageRiskDescriptions.Add("DO NOT ALLOW SPILLAGE TO ENTER MAINS");
These seem to be adding elements to the private ArrayList _SpillageRiskDescriptions
(through the property) whereas I would've expected this to cause a problem. Therefore am I correct in thinking that properties return a reference to the original variable and not passing it by value? Is this because ArrayList
is a reference type? Will the same happen with an int
(for example?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
其他答案已经正确回答了您的主要问题:引用类型的属性的值是对实例<的引用 /em> 引用类型。
更大的问题是“现在你该怎么办?”想必您不想要能够获取列表的代码能够更改列表。
这里有几个选项。
首先,无论您做什么,我都建议您立即停止使用 ArrayList,并开始使用更现代、更安全的类型来存储事物列表。
List
立即浮现在脑海中。其次,属性的setter是否必须是公开的?您是否希望任何人都能够更改该列表?或者类型本身应该负责以某种方式更新它?我会考虑将设置器设为私有。
第三,我们为“琐碎”属性提供了更紧凑的语法。您可能会说
,编译器将为您生成支持字段。
请注意,
List
仍然允许突变。如果所有客户端关心的是能够一次迭代列表中的一件事,那么你可以这样做:
现在调用者不可能改变列表,因为你给他们的只是一个迭代器它,不能访问列表本身。
或者你可以这样做:
现在调用者有一个列表的只读视图,如果他们尝试修改它,就会抛出异常。
The other answers have correctly answered your primary question: that the value of a property of reference type is a reference to an instance of the reference type.
The larger question is "now what do you do about it?" Presumably you do not want code that can obtain the list to be able to change it.
There are several options here.
First, no matter what you do I recommend that you stop using ArrayList right now and start using a more modern, safe type for storing a list of things.
List<string>
comes immediately to mind.Second, is it necessary that the setter of the property be public? Do you want just anyone to be able to change that list? Or should the type itself be responsible for updating it somehow? I'd consider making the setter private.
Third, we have a more compact syntax for a "trivial" property. You could be saying
and the compiler will generate the backing field for you.
Note that
List<string>
still allows mutation.If all the client cares about is being able to iterate over the list one thing at a time, then you can do this:
and now it is impossible for the caller to mutate the list, because all you're giving them is an iterator over it, not access to the list itself.
Or you could do:
And now the caller has a read-only view of the list that will throw an exception if they attempt to modify it.
C# 通过引用返回对象。
唯一不按值返回的是:
原始类型。
结构类型。
枚举。
C# returns objects by reference.
Only things that aren't returned by value are:
Primitive types.
Struct types.
Enums.
这与它本身是否是财产无关;它是属性的数据类型。在本例中,您使用的是 ArrayList,它是一个通过引用传递的类。如果该属性的类型为
int
,则它将按值传递。It has nothing to do with whether it is a property per se; it is the data type of the property. In this case, you are using
ArrayList
which is a class that is passed by reference. If the property were typed as anint
it would be passed by value.属性实际上是两个方法的对 - setter 和 getter。它们按原样传递支持字段(或用作源/目标的任何内容)的值。因此,对于引用类型,传递引用,对于值类型,传递值。
请注意,通过将
ArrayList
实例分配到您的属性中,您基本上可以替换支持字段指向的ArrayList
实例。回答您的具体问题:
不,通过使用 getter,您不会获得对
_SpillageRiskDescriptions
字段的引用。您将获得该字段的值,该字段是对(动态分配的)ArrayList
实例的引用。是的,ArrayList 是一个引用类型,因此您会收到对特定 ArrayList 实例的引用。
是的,也不是。 是,您将收到
int
字段的值。 不,int
是一种值类型,因此如果您修改该值而不显式将其设置回来,则底层字段不会受到影响。A property is actually a pair of two methods — a setter and a getter. They pass the value of the backing field (or whatever is used as the source / destination) as it is. Hence, for reference types the reference is passed, and for value types the value is passed.
Note that by assigning an
ArrayList
instance into your property you basically replace theArrayList
instance pointed to by the backing field.To answer your particular questions:
No, by using the getter you don't get a reference to the
_SpillageRiskDescriptions
field. You get the value of the field which is a reference to a (dynamically allocated)ArrayList
instance.Yes,
ArrayList
is a reference type and thus you receive the reference to the particularArrayList
instance.Yes and no. Yes, you will receive the value of an
int
field. And no,int
is a value type, so if you modify the value without explicitly setting it back, the underlying field won't be affected.和房产没有任何关系。
在这种情况下,您将按值传递对数组列表的引用。
如果您执行类似的操作
,那么对数组列表的引用将被修改。
如果您要做类似的事情
,那么对数组列表的原始引用根本不会改变。
但是,如果您要通过引用传递引用(例如:),
那么您的属性最终将得到一个包含单个项目的新数组列表。
It doesn't have anything to with the property.
In this case, you are passing a reference to the array list by value.
If you do something like
then the reference to the array list will be modified.
If you were to do something like
then the original reference to the array list would not be changed at all.
But if you were to pass the reference by reference such as in:
then your property would end up with a new array list with a single item.
从技术上讲,它总是按值传递,但您必须了解正在传递的内容。由于它是引用类型,因此您将传递回引用(但按值)。
希望这是有道理的。您始终按值传回结果,但如果类型是引用,则您将按值传回引用,这意味着您可以更改对象,但不能更改它引用的对象。
Technically it's always by value, but you have to understand what is being passed. Since it's a reference type, you are passing a reference back (but by value).
Hope that makes sense. You always pass the result back by value, but if the type is a reference you are passing the reference back by value, which means you can change the object, but not which object it refers to.