用作参数时可变的值

时间:2016-04-11 20:18:30

标签: c#

我的方法采用SearchCriteria参数,然后将这一个参数传递给2个方法。在GetFoo1中,条件对象在被传递给另一个查询数据库的方法之前被修改。

我的期望是,标准对象应该在此方法的范围内保持不变。也就是说,完全相同的对象被传递给GetFoo1和GetFoo2,因为我没有通过引用传递标准。 https://msdn.microsoft.com/en-us/library/s6938f28.aspx

public virtual async Task<SnapshotObject> GetSnapshot(SearchCriteria criteria)
    {
        var snapshot = new SnapshotObject();

        snapshot.Foo1 = await GetFoo1(criteria);
        snapshot.Foo2 = await GetFoo2(criteria);

        return snapshot;
    }

在这个例子中,当我调用GetFoo1时,我希望按值传递标准。出于某种原因,当我将criteria对象传递给GetFoo1时,修改会在我将其传递给GetFoo2时保持不变,就像我通过引用传递一样。

1 个答案:

答案 0 :(得分:4)

这种情况正在发生,因为SearchCriteria是一个类。因此,即使它是通过值传递的,传递的值也是对该对象的引用。

这意味着从调用者和访问同一对象的其他人可以看到对象本身的任何更改:

var list = new List<string>();
MyMethod(list);
if(list.Count == 0)   // this one will be false because list now have 1 item
    ....

void MyMethod(List<string> list)
{
    list.Add("hey!");
}

但是,它们无法替换整个对象:

var list = new List<string>();
MyMethod(list);
if(list.Count == 0)   // this one will be true
    ....

void MyMethod(List<string> list)
{
    list = new List<string>() { "hey!" }; // does not affect the caller.
}

如果您通过引用传递该参数,则第二个示例会将调用者更改为指向新创建的List<string>,而不是其中包含1个项目。

在“通过价值传递参考类型”部分中链接到的文章中解释:

  

以下示例演示如何将值引用的引用类型参数arr传递给方法Change因为参数是arr的引用,所以可以更改数组元素的值。但是,尝试将参数重新分配给不同的内存位置只能在方法内部工作并且不会影响原始变量arr