属性 - 按值或参考?

m.e*_*son 7 .net c# properties pass-by-reference pass-by-value

我有以下公共财产,暴露了Arraylist:

public ArrayList SpillageRiskDescriptions
        {
            get
            {
                return _SpillageRiskDescriptions;
            }
            set
            {
                _SpillageRiskDescriptions = value;
            }
        }
Run Code Online (Sandbox Code Playgroud)

在其他地方,我正在打电话

SpillageRiskDescriptions.Add("VENTILATE AREA");
SpillageRiskDescriptions.Add("DO NOT ALLOW SPILLAGE TO ENTER MAINS");
Run Code Online (Sandbox Code Playgroud)

这些似乎是向私有ArrayList添加元素_SpillageRiskDescriptions(通过属性),而我希望这会导致问题.因此,我认为属性返回对原始变量的引用而不是按传递它是否正确?这是因为ArrayList是参考类型吗?int(例如?)会发生同样的情况吗?

Jam*_*are 11

从技术上讲,它总是靠价值,但你必须了解传递的是什么.因为它是一个引用类型,所以你传回一个引用(但是按值).

希望有道理.您总是按值传递结果,但如果类型是引用,则您将按值传递引用,这意味着您可以更改对象,但不能更改它引用的对象.

  • 可以把它想象成C++,你可以传递指向一个对象的指针,你可以改变指针所指向的东西,但你不能指向别的东西,因为你有指针的副本而不是原始指针.如果要更改它指向的对象,则必须将指针传递给指针(或指针的引用).这就是为什么在C#中,如果要更改引用的对象,则需要ref和out关键字. (2认同)

Eri*_*ert 8

其他答案正确回答您的主要问题:即价值一的引用类型的属性引用一个实例引用类型的.

更大的问题是"现在你怎么办呢?" 据推测,您希望能够获取列表的代码能够更改它.

这里有几种选择.

首先,无论你做什么我建议你立即停止使用ArrayList并开始使用更现代,安全的类型来存储事物列表.List<string>马上就会想起来.

其次,是否有必要将二传手的财产是公开的?你想让任何人都能改变这个清单吗?或者类型本身是否应该以某种方式更新它?我会考虑将setter设为私有.

第三,对于"普通"属性,我们有一个更紧凑的语法.你可能会说

public List<string> SpillageListDescriptions { get; private set; }
Run Code Online (Sandbox Code Playgroud)

并且编译器将为您生成支持字段.

请注意,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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在调用者不可能改变列表,因为你给它们的只是一个迭代器,而不是访问列表本身.

或者你可以这样做:

private List<string> descriptions = whatever;
public IList<string> SpillageListDescriptions 
{ 
    get 
    {
        return new ReadOnlyCollection<string>(descriptions); 
    }
}
Run Code Online (Sandbox Code Playgroud)

现在调用者有一个列表的只读视图,如果他们试图修改它就会抛出异常.