C# 将对象作为参数传递
应用程序正在打印24,但如果我们知道没有ref关键字,只传递对象的一个副本,并且不对原始对象进行更改,那么它不应该打印18。 我创建了一个名为myclass的类和一个名为me的对象。年龄是myclass类中的公共变量。 我把我的年龄设为18岁,通过方法显示,我把它改为24岁C# 将对象作为参数传递,c#,C#,应用程序正在打印24,但如果我们知道没有ref关键字,只传递对象的一个副本,并且不对原始对象进行更改,那么它不应该打印18。 我创建了一个名为myclass的类和一个名为me的对象。年龄是myclass类中的公共变量。 我把我的年龄设为18岁,通过方法显示,我把它改为24岁 class Program { static void Main(string[] args) { myclass me = new myclass(); me
class Program
{
static void Main(string[] args)
{
myclass me = new myclass();
me.age = 18;
show(me);
Console.WriteLine(me.age);
Console.ReadLine();
}
public static void show( myclass you)
{
you.age = 24;
}
}
class myclass
{
public int age;
}
您正在向函数发送一个对象 不是原子类型或结构,因此它是通过引用发送的(这是C#的工作方式),在函数中更改此对象的任何内容都将在原始对象中更改,因为它是相同的
有关传递参数的详细信息:您混淆了值类型和引用类型
public void addTwo(int a)
{
a += 2;
}
...
int a = 5;
addTwo(a);
Console.WriteLine(a); // will give "5";
对于引用类型(定义为
class
而不是struct
的任何对象),您传递的是对对象的引用,而不是副本。因此,实际上您正在更改对象。它正在打印正确的内容
myclass
是一个对象,默认行为是在C#中传递对象的引用,因此当您不指定任何内容时,就传递引用
但是,如果您声明
struct myclass
,您将拥有所需的行为,因为默认情况下,结构不是引用。不要混淆变量和变量指向的对象
如果您有:
MyClass myVar = new MyClass();
MyClass myVar2 = myVar;
这将只创建一个对象的单个实例,但会创建指向它的两个变量
您的参数也发生了同样的情况:you
是变量me
的副本,但两者都指向同一个对象。因此,当您修改you.age
时,您也在修改me.age
在你的功能中,如果你这样做了
you = new myClass();
只有这样,me
和you
才会引用不同的对象。如果这样做,me
仍会指向原始对象
如果将ref
添加到参数you
,则
you = new myClass();
然后变量me
将更新为指向同一对象
对于对象,你需要将变量与变量点分开。
你可能把它与C++类混淆了。在C语言中,类是引用类型,这意味着每当你有一个类的变量,这个变量不包含对象本身时,它只包含一个引用。(可以将其视为指针)。因此,当您将对象传递给方法时,您实际上传递了对该对象的引用。这意味着您观察到的行为是正确的C#还支持值类型(与Java不同),您可以使用
struct
而不是class
创建值类型。如果您将myclass
更改为srtuct
,您将获得预期的行为。我已经编辑了您的标题。请参见“”,其中的共识是“不,它们不应该”。“没有ref关键字,只传递对象的副本,不对原始对象进行更改”是不正确的。正确的语句是“没有ref
或out
关键字,传递值的副本;如果值来自变量,则不对原始变量进行更改。"ref
为变量创建别名。这非常令人困惑。struct
s继承自Object
,但它们不是对象?如果这只是默认情况,是否意味着您可以通过值传递类的实例?在c中,所有内容都继承自Object
。但是struct
首先继承从System.ValueType
(然后从对象继承而来)中。差异在编译器级别产生。当编译器“看到”时某个东西继承自System.ValueType
它传递值,而不是继承自System.ValueType
它传递引用
you = new myClass();