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