C# 对象真的是引用类型吗?

C# 对象真的是引用类型吗?,c#,types,reference-type,C#,Types,Reference Type,据我所知,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,这很好,因为您可以将它解释

据我所知,
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;
}

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

这不是不同的行为,你在做不同的事情

这将与您的
对象
示例完全相同:

    public void ChangeValue(MyClass classobj)
    {
        classobj = null;
    }
这将作为您的第一个示例(假设您将通过
MyClass
instance):

这里真正发生的是,当您指定参数(不是参数的属性或字段)时,您只更改该参数的值。调用代码中的原始值和变量保持不变

同样的情况也发生在这里:

MyClass a = new MyClass();
MyClass b = a;
a = null;
// b still contains the value created in the first line
简单地说,引用变量保存实际值的指针(内存地址)。 通过更改变量的值,可以使它指向不同的对象或null。
但是,当您执行
a.field=2
时,这意味着您正在按值将对象
a
引用并更改其
字段
成员值。

您将
对象值
传递给
更改值(对象对象对象值)
,该值是一个引用。然后更改此值,但不更改
myObject
的值


您必须将其作为
ChangeValue(ref object objectValue)
进行传递,才能一个接一个地传递引用的值。

您在这里实际上做了两件不同的事情
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);

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

请阅读:关于方法参数传递的一个很好的解释。请记住:
object
是一个别名
System.object
,它是一个类,这意味着它是一个引用类型。另外:我对myclass对象做了同样的事情,我创建了它的对象,然后将它传递给Changevalue(myclass objClass),这个值是一个引用类型。然后我把它的值改为20,它也反映了我的调用者对象值。那么为什么它对myClass对象有效?@wikinevis,因为您实际上没有更改myClass的值(myClass的值是一个引用),所以您更改了myClass引用的对象的值。我明白您的意思,这是正确的。我的问题伴随着你的解释而来,这就是“为什么myClass的值在ChangeValue(myClass classobj)中发生变化?”想象一下myClass引用的副本出现在方法中,我改变了classobj.Number=0;那么它将如何通知打电话的人这一变化?这不是告诉打电话的人这一变化的问题。调用方和方法都可以查看和修改同一个对象,因为它们都有对该对象的引用。如果调用方在方法运行后查看对象,它将看到更改,因为该方法更改了相同的对象。
ChangeValue(ref myObject);