【问题标题】:Why the static variable is not set to null when the local variable storing that reference is set to null?当存储该引用的局部变量设置为空时,为什么静态变量不设置为空?
【发布时间】:2013-12-29 10:28:29
【问题描述】:

我有以下代码:

public class Employee
{
    public string Name { get; set; }
}

public class InstanceManager
{
    public static Employee employee;

    public static Employee GetEmployee()
    {
        if(employee == null)
        {
            employee = new Employee {Name = "Tom"};
        }

        return employee;
    }
}

public class TestClass
{

    public void Test()
    {
        Employee emp = InstanceManager.GetEmployee();
        var name = emp.Name;
        emp = null;
        var name2 = InstanceManager.GetEmployee().Name;
    }
}

Test() 方法中,局部变量emp 正在引用InstanceManager.Employee 对象。然后,我将emp 设置为null

  • 这不是说我将InstanceManager.Employee 设置为null 吗?
  • 如果我调试这段代码,我发现InstanceManageremployee 静态变量不是null!为什么?

(当我在emp = null; 之后调用此方法时,我期望GetEmployee() 方法将创建并返回新的Employee 对象。)

【问题讨论】:

  • empEmployee 的一个实例,由GetEmployee() 返回。将该对象设置为 null 不会影响返回该对象的方法。
  • @Jamie Dixon :但是emp 引用了GetEmployee() 返回的对象。那么为什么不将InstanceManager的那个变量设置为null呢? emp 是否有单独的副本?

标签: c# .net pass-by-reference static-members


【解决方案1】:

这不是说我将 InstanceManager.Employee 设置为 null 吗?

没有。您只是将“emp”设置为 null 的局部变量。

如果我调试这段代码,我发现 InstanceManager 的雇员静态变量不为空!为什么?

您需要为员工属性实现公共设置器。您可以将财产公开。

您也可以在实例管理器中添加类似的内容:

           public static void ClearEmployee()
            {
                employee = null;
            }

因为 this 明确引用了静态字段。

【讨论】:

    【解决方案2】:

    你所做的基本上是:

    Employee emp = InstanceManager.GetEmployee();
    

    emp 现在是对employee 实例的引用

    emp = null;
    

    emp 不再是对employee 实例的引用

    var name2 = InstanceManager.GetEmployee().Name;
    

    name2 现在是对employee.Name 实例的引用

    您永远不会将 null 设置为 InstanceManager.employee。顺便说一句,甚至没有公开的设置器。

    【讨论】:

    • empemployee 不是指向同一个对象吗?那么为什么将emp 设置为null 不会使InstanceManager.employee 为null? emp 是否有单独的副本?顺便说一句,如果我有公共设置器,也会有相同的行为。
    • @CSharpLearner 将emp 设置为空只会破坏empemployee 之间的链接。 emp 实际上只是一个指向employee指针
    • @ken2k:不,emp 不是指向employee 的指针。 empemployee 都是直接指向对象的指针,而不是相互之间
    【解决方案3】:

    在这一行之后:

    Employee emp = InstanceManager.GetEmployee();
    

    你的情况是这样的:

    当你这样做时:

    emp = null;
    

    之后,您不会更改静态变量 employee。您只是将emp 设置为引用另一个(在本例中为null)“位置”。更准确地说-您将其设置为不指向任何东西。静态的employee 一直指向它所在的位置。这条线的效果可以这样可视化:

    【讨论】:

    • 我喜欢你。这是可以解释的最佳答案。 :)
    【解决方案4】:

    "emp" 是 Test 类中 Employee 的一个新实例。它不指静态变量雇员。因为,

        Employee emp = InstanceManager.GetEmployee();
    

    将获取值并分配给emp。

    结论:实例emp(Test类)和employee(InstanceManager类)是不同的。

    【讨论】:

    • empemployee 不是两个不同的“实例”。它们是指向同一个“实例”的两个不同“引用”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 1970-01-01
    • 2012-11-07
    • 2014-03-24
    • 1970-01-01
    • 2016-01-11
    • 1970-01-01
    相关资源
    最近更新 更多