2

据我所知ClassObject是参考类型。

我有以下方法来更改值

public void ChangeValue(MyClass classobj)
{
    classobj.Number = classobj.Number*2;
}

我调用该方法将值加倍

var myClass=new MyClass();
int myNumber = 10;
myClass.Number = myNumber;
ChangeValue(myClass);

它将返回 20,这很好,因为您可以将其解释为当您创建类的对象然后它将引用传递给方法并更新引用值。

但我的问题是为什么它不会发生在 Object 类型中。换句话说,为什么当我制作对象并为其分配一些值时,如下所示

 object myObject = new object();
 string sometext  = "Some object value";
 myObject = sometext;
 ChangeValue(myObject)

执行方法后它不会改变值

public void ChangeValue(object objectValue)
{
    objectValue = null;
}

我知道方法的参数是值类型,但无法理解它对两种引用类型有不同的行为。

4

3 回答 3

2

你实际上在这里做两件不同的事情。Object并且您MyClass确实都是引用类型,这意味着您将对实际对象的引用传递给ChangeValue方法。但是,您在方法中看到的引用是调用者持有的引用的副本。它们指向同一个对象,因此当您在方法中操作对象时,方法的调用者可以看到您的更改,但对方法内部实际引用的更改只会影响方法本身。

总结一下,对象是通过引用传递的,但那些引用是通过传递的。

在你的方法中

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);

因此在调用站点很明显它可能会返回指向不同的对象。知道这一点很重要,因为如果引用意外地指向不同的对象,您可能仍然有依赖旧值的东西并最终陷入可怕的混乱之中。

于 2013-02-22T11:41:18.540 回答
1

您将 传递objectValueChangeValue(object objectValue)by 值,该值是一个引用。然后你改变这个值,而不是myObject.

您必须将其传递为ChangeValue(ref object objectValue)实际通过引用传递引用的值。

于 2013-02-22T11:38:48.403 回答
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成员值。

于 2013-02-22T11:38:24.963 回答