2013-12-11 83 views
1

我已经以下代码:当存储该引用的局部变量设置为空时,为什么静态变量未设置为空?

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
  • 如果我调试这段代码,我发现InstanceManager的静态变量不是null!为什么?

(我期待新的员工对象将被创建,当我emp = null;之后,调用此方法由GetEmployee()方法返回。)

+0

'emp'是由'GetEmployee()'返回的'Employee'的一个实例。将该对象设置为null对返回对象的方法没有影响。 –

+0

@Jamie Dixon:但'emp'引用'GetEmployee()'返回的对象。那为什么不将InstanceManager的变量设置为null? 'emp'是否持有单独的副本? – Learner

回答

9

这一行后:

Employee emp = InstanceManager.GetEmployee(); 

你的情况是这样的:

enter image description here

当你这样做:

emp = null; 

之后,你不改变静变量employee。你只是设置emp来引用另一个(在这种情况下为null)“位置”。更确切地说 - 你将它设置为不指向任何东西。静态employee一直指向它的位置。这条线的效果可以可视化这样的:

enter image description here

+0

我喜欢你。这是最好解释的答案。 :) –

-1

难道这不是意味着,我设置InstanceManager.Employee为空?

不,你只是设置“emp”,iself作为局部变量为null。

如果我调试此代码,我发现该InstanceManager的员工静态变量不为null!为什么?

您需要为employee属性实现公共setter。你可以公开财产。

您还可以添加像这样的实例管理器:

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

由于这明确地引用静态字段。

6

你在做什么基本上是:

Employee emp = InstanceManager.GetEmployee(); 

emp现在是到employee实例

emp = null; 

emp的引用,没有更多的employee实例

var name2 = InstanceManager.GetEmployee().Name; 
参考

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

您从不将null设置为InstanceManager.employee。它甚至没有一个公开的二传手。

+0

'emp'和'employee'是否指向同一个对象?那么为什么将'emp'设置为null并不会使'InstanceManager.employee'为空? 'emp'持有单独的副本吗?顺便说一句,如果我有公共二传手,也会有同样的行为。 – Learner

+1

@CSharpLearner将'emp'设置为null只是_breaks_ emp'和'employee'之间的链接。 'emp'实际上只是一个'员工'的指针。 – ken2k

+0

@ ken2k:不,'emp'不是'employee'的指针。 'emp'和'employee'都是直接指向对象的指针,不是通过对方 –

-1

“EMP”是员工的测试类中的新instace。它不涉及静态变量员工。因为,

Employee emp = InstanceManager.GetEmployee(); 

将获得值并分配给emp。

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

+0

'emp'和'employee'不是两个不同的“实例”。它们是指向相同“实例”的两个不同“参考”。 – Learner