当参数是引用类型并且是以传值的方式传入参数的时候,方法传入的是这个对象的引用的一个副本,相当于是以一个引用的值按照传值的方式调用方法。这个引用在方法内部会生成一个副本,就像普通的值类型变量一样,但是由于这个引用的副本和原来方法外面的类型的引用是指向了同一个对象,所以方法内部对这个对象进行的各种操作(改变对象的属性等)看上去就像是按引用传递变量了,返回之后对象会发生变化。但是如果在方法内部对这个引用的副本进行了赋值操作,那么这个引用的副本就不再指向原来的对象了,方法返回后,原来的对象自然也不会发生变化。

    Python解析:

# -*- coding:utf-8 -*-

lst = [1, 2, 3]

def func1(lst):
    lst.append(4)

def func2(lst):
    lst = lst[:-1] # 赋值操作,lst不再指向原来的对象了
    print(lst)

func1(lst)
print(lst) # lst = [1, 2, 3, 4], 函数内改变lst的属性,同样反应到了函数外的lst变量

func2(lst)
print(lst) # lst = [1, 2, 3],

    结论:在函数的调用中,传入引用类型做参数的时候,它仍然是以值传递的方式传递参数的,只不过传入方法内部的是对象的引用的值。同样的,C#和Java也有相同过的问题。C#可以增加ref关键字来解决这个问题。