在方法中更改类属性值

时间:2017-01-02 16:25:40

标签: c# class oop reference-type

我有以下代码

public class Myclass
{
    public int someProp{ get; set; };
}
public class Program
{
    public static void Main(string[] args)
    {
        Myclass m = new Myclass();
        Console.WriteLine(m.someProp);
        ChangeValue(m);
        Console.WriteLine(m.someProp);
        SetToNull(m);
        Console.WriteLine(m.someProp);
        Console.ReadKey();
    }
    static void ChangeValue(Myclass m)
    {
        m.someProp = 10;
    }
    static void SetToNull(Myclass m)
    {
        m = null;
    }
}

结果是0 10 10
我想知道为什么在我将类设置为null后它显示为10.
传递给方法的m是对象的副本还是仅供参考。

4 个答案:

答案 0 :(得分:2)

首先我想注意你是在询问字段而不是属性, 属性以这种方式配置:

public class Myclass
{
    public int someProp{ get; set; }
}

关于您的问题 你是对的,当你将一个实例传递给方法时,你正在向这个实例传递一个“指针”,你不能用这种方式替换实例,你可以只改变它的属性/字段。 为了替换/更改实例本身,您需要使用ref关键字传递引用。

固定代码为:

public class Myclass
{
    public int someProp;
}
public class Program
{
    public static void Main(string[] args)
    {
        Myclass m = new Myclass();
        Console.WriteLine(m.someProp);
        ChangeValue(m);
        Console.WriteLine(m.someProp);
        SetToNull(ref m);
        Console.WriteLine(m.someProp);
        Console.ReadKey();
    }
    static void ChangeValue(Myclass m)
    {
        m.someProp = 10;
    }
    static void SetToNull(ref Myclass m)
    {
        m = null;
    }
}

有些地方需要阅读以获取更多信息:

答案 1 :(得分:2)

  

传递给方法的m是对象的副本还是仅仅是引用。

您正在将“m”引用的副本传递给方法。如果要将实际引用传递给内存中的MyClass对象,可以使用 ref 关键字:

public class Program
{
    public static void Main(string[] args)
    {
        Myclass m = new Myclass();
        SetToNull(ref m);
        if(m == null)
            Console.WriteLine("NULL!");
        Console.ReadKey();
    }

    static void SetToNull(ref Myclass m)
    {
        m = null;
    }
}

然后,SetToNull方法将实际的“m”引用设置为空引用。

答案 2 :(得分:1)

传递的m只是一个参考。

设置对象的属性时,您需要更改引用对象的属性。

当您将m本身设置为null时,您正在更改m引用的内容,这就是Main中原始引用仍指向原始对象的原因

答案 3 :(得分:1)

SetToNull函数为例,可以重写如下。因此,您可以看到您没有在主函数中更改m的值,而是更改_m_m也是一个引用,是m

的副本
static void SetToNull(Myclass _m)
{
    _m = null;
}