C# 将对象作为参数传递

C# 将对象作为参数传递,c#,C#,应用程序正在打印24,但如果我们知道没有ref关键字,只传递对象的一个副本,并且不对原始对象进行更改,那么它不应该打印18。 我创建了一个名为myclass的类和一个名为me的对象。年龄是myclass类中的公共变量。 我把我的年龄设为18岁,通过方法显示,我把它改为24岁 class Program { static void Main(string[] args) { myclass me = new myclass(); me

应用程序正在打印24,但如果我们知道没有ref关键字,只传递对象的一个副本,并且不对原始对象进行更改,那么它不应该打印18。 我创建了一个名为myclass的类和一个名为me的对象。年龄是myclass类中的公共变量。 我把我的年龄设为18岁,通过方法显示,我把它改为24岁

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