我有以下显示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
(例如?)
答案 0 :(得分:11)
从技术上讲,它总是按价值计算,但你必须了解传递的内容。因为它是一个引用类型,所以你传回一个引用(但是按值)。
希望这是有道理的。您总是按值传递结果,但如果类型是引用,则您将按值传递引用,这意味着您可以更改对象,但不能更改引用的对象。
答案 1 :(得分:8)
其他答案已正确回答了您的主要问题:参考类型属性的值是引用到引用类型的实例。
更大的问题是“现在你怎么办?”据推测,您不想要获取列表的代码能够更改。
这里有几种选择。
首先,无论你做什么我建议你立即停止使用ArrayList并开始使用更现代,安全的类型来存储事物列表。我会立刻想到List<string>
。
其次,该属性的 setter 是否必须公开?你想让任何人都能改变这个清单吗?或者类型本身是否应该以某种方式更新它?我会考虑将setter设为私有。
第三,对于“普通”属性,我们有一个更紧凑的语法。你可能会说
public List<string> SpillageListDescriptions { get; private set; }
并且编译器将为您生成支持字段。
请注意List<string>
仍允许变异。
如果所有客户关心的是能够一次迭代列表,那么你可以这样做:
private List<string> descriptions = whatever;
public IEnumerable<string> SpillageListDescriptions
{
get
{
if (descriptions == null) yield break;
foreach(var description in descriptions)
yield return description;
}
}
现在调用者不可能改变列表,因为你给它们的只是一个迭代器,而不是访问列表本身。
或者你可以这样做:
private List<string> descriptions = whatever;
public IList<string> SpillageListDescriptions
{
get
{
return new ReadOnlyCollection<string>(descriptions);
}
}
现在调用者有一个列表的只读视图,如果他们试图修改它就会抛出异常。
答案 2 :(得分:2)
C#通过引用返回对象。
只有未按价值返回的内容为:
原始类型。
结构类型。
枚举。
答案 3 :(得分:1)
它与财产本身无关;它是属性的数据类型。在这种情况下,您使用的是ArrayList
,它是通过引用传递的类。如果属性被键入为int
,则它将按值传递。
答案 4 :(得分:0)
属性实际上是一对两种方法 - 一个setter和一个getter。它们原样传递支持字段的值(或者用作源/目标的任何值)。因此,对于引用类型,传递引用,对于值类型,传递值。
// this is how the getter method looks like
public ArrayList get_SpillageRiskDescriptions()
{
return _SpillageRiskDescriptions;
}
// this is how the setter method looks like
public void set_SpillageRiskDescriptions(ArrayList value)
{
_SpillageRiskDescriptions = value;
}
请注意,通过为您的属性分配ArrayList
实例,您基本上替换支持字段指向的ArrayList
实例。
回答您的具体问题:
因此,我认为属性会将引用返回到原始变量而不是通过值传递它吗?
不,通过使用getter,您无法获得_SpillageRiskDescriptions
字段的引用。您将获得该字段的值,该字段是对(动态分配的)ArrayList
实例的引用。
这是因为
ArrayList
是引用类型吗?
是的,ArrayList
是一种引用类型,因此您会收到对特定ArrayList
实例的引用。
会发生同样的情况吗?
int
(例如?)
是和否。 是,您将收到int
字段的值。并且没有,int
是一种值类型,因此如果您在未明确设置值的情况下修改该值,则基础字段不会受到影响。
答案 5 :(得分:0)
该物业没有任何内容。
在这种情况下,您将按值传递对数组列表的引用。
如果您执行类似
的操作 void AddSomethingToArrayList(ArrayList spillageRiskDescriptions){
spillageRiskDescriptions.Add("Something");
}
然后将修改对数组列表的引用。
如果您要做类似
的事情 void ReassignArrayList(ArrayList spillageRiskDescriptions){
spillageRiskDescriptions = new ArrayList();
spillageRiskDescriptions.Add("Something");
}
然后对数组列表的原始引用根本不会改变。
但是如果您通过引用传递引用,例如:
void ReassignArrayListByRef(ref ArrayList spillageRiskDescriptions){
spillageRiskDescriptions = new ArrayList();
spillageRiskDescriptions.Add("Something");
}
然后你的属性最终会得到一个包含单个项目的新数组列表。