据我所知Class
和Object
是引用类型。
我有以下方法来更改值
public void ChangeValue(MyClass classobj)
{
classobj.Number = classobj.Number*2;
}
我调用方法将值加倍
var myClass=new MyClass();
int myNumber = 10;
myClass.Number = myNumber;
ChangeValue(myClass);
它将返回20,这很好,因为你可以将它解释为当你创建类的对象然后它传递方法的引用,它将更新参考值。
但我的问题是为什么它没有发生对象类型。换句话说,为什么当我创建对象并为其分配一些值时,如下面
object myObject = new object();
string sometext = "Some object value";
myObject = sometext;
ChangeValue(myObject)
执行方法后不会改变值
public void ChangeValue(object objectValue)
{
objectValue = null;
}
我知道方法的参数是值类型但无法理解它对两种引用类型有不同的行为。
答案 0 :(得分:2)
你实际上在这里做了两件不同的事情。 Object
和MyClass
确实都是引用类型,这意味着您将对实际对象的引用传递给ChangeValue
方法。但是,您在方法中看到的引用是调用者持有的引用的副本。它们指向同一个对象,因此当您在方法中操作对象时,方法的调用者可以看到您的更改,但是对方法内部实际引用的更改只会影响方法本身。
在尝试总结时,对象由引用传递,但这些引用由 value 传递。
在你的方法中
public void ChangeValue(object objectValue)
{
objectValue = null;
}
您实际执行的操作是重新分配引用objectValue
,该引用是调用方具有的名为myObject
的引用的副本。因为该方法只有副本,所以它根本不会影响调用者的引用。
有一种方法可以使这项工作,您必须通过引用传递引用。这总是让我头疼,但这就是ref
关键字的用途。
public void ChangeValue(ref object objectValue)
{
objectValue = null; // this is the SAME reference as the caller has, so the caller will see this change
}
然而,它也必须这样称呼:
ChangeValue(ref myObject);
因此在调用网站上很明显它可能会回来指向另一个对象。重要的是要知道,因为如果引用意外地指向不同的对象,你可能仍然依赖于旧值并最终陷入可怕的混乱局面。
答案 1 :(得分:1)
您将objectValue
传递给ChangeValue(object objectValue)
的值,此值是参考。然后,您更改此值,但不更改myObject
。
您必须将其作为ChangeValue(ref object objectValue)
传递,才能通过引用实际传递引用值。
答案 2 :(得分:0)
这不是一个不同的行为,你正在做不同的事情
这与您的object
示例完全相同:
public void ChangeValue(MyClass classobj)
{
classobj = null;
}
这将作为您的第一个示例(假设您将通过MyClass
实例):
public void ChangeValue(object objectValue)
{
((MyClass)objectValue).Number *= 2;
}
这里真正发生的是,当您分配参数(不是属性或参数字段)时,您只是更改该参数的值。调用代码中的原始值和变量保持不变。
这里也是如此:
MyClass a = new MyClass();
MyClass b = a;
a = null;
// b still contains the value created in the first line
简单来说,引用变量保存实际值的指针(内存地址)。
通过更改变量的值,可以使其指向不同的对象或null。
但是,当您执行a.field=2
时,这意味着您正在引用a
引用的对象并更改其field
成员值。