将类的变量作为先前定义为null

时间:2016-09-16 20:53:51

标签: c# oop pointers parameters instance

我以前从未意识到这样的问题。如果我传递一个特定类型但尚未实例化的变量,那么它不应该被视为指针吗?在这个例子中,当我回到click事件的范围时,如果方法GetEmployee创建一个新实例,为什么我变为null。

我知道要使它工作我可以将参数定义为ref或out,但是Employee是一个最初定义为null的类,但是当我执行new时它会在内存中分配一个空格而且它不应该被链接到变量?为什么我以后会丢失这个值?

如果我已经传递了一个对象,当我回到click事件的范围时,内部方法中所有修改过的属性都将保留,那么场景将会完全不同。

这不起作用

    protected void btnTest_Click(object sender, System.EventArgs e)
    {
        Employee employee = null;
        bool created = GetEmployee(employee);
    }

这将有效

    protected void btnTest_Click(object sender, System.EventArgs e)
    {
        Employee employee = new Employee();
        bool created = GetEmployee(employee);
    }

其余的

    private bool GetEmployee(Employee employee)
    {
        if (employee == null)
        {
            employee = new Employee();

        }
        employee.ID = 1;
        employee.Name = "John";
        return true;
    }

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

更新

使事情变得复杂一点。这也会失败,因为对象从未被设置为与null

不同的东西
    protected void btnTest_Click(object sender, System.EventArgs e)
    {
        int id = 1;
        Employee employee = this.LoadFromDatabase(id);
        bool created = GetEmployee(employee);
    }

    private Employee LoadFromDatabase(id)
    {
        //In the inner service method if it is not found it will return null
        return Service.Instance.LoadFromDatabase(id);
    }

    private bool GetEmployee(Employee employee)
    {
        if (employee == null)
        {
            employee = new Employee();

        }
        employee.ID = 1;
        employee.Name = "John";
        return true;
    }

3 个答案:

答案 0 :(得分:2)

虽然调用者可以修改员工成员,但对员工本身的引用却不能。在C#中传入引用类型参数时,您可以修改该对象的成员并查看调用者中的更改。但是,引用本身是按值传递的,并且分配给参数将不会执行任何操作。要做你想做的事情,只需返回员工而不是错误地尝试修改引用:

private Employee GetEmployee(Employee employee)
{
    if (employee == null)
    {
        return new Employee()
        {
            ID = 1,
            Name = "John",
        };
    }

    employee.ID = 1;
    employee.Name = "John";
    return employee;
}

答案 1 :(得分:0)

Employee是一种引用类型,这意味着它实际上是员工数据的地址。

employee中的GetEmployee参数只是该地址的副本。由于您知道地址,因此您可以更改地址上的信息,但由于它只是一个副本,因此您对地址本身所做的任何更改(例如employee = new Employee();)都不会影响您传入的地址。

执行employee = new Employee();时,您已使用新地址覆盖复制的地址,该地址指向内存中完全不同的员工。这就是为什么你没有看到你传入的员工有任何变化的原因。

答案 2 :(得分:0)

当您将 引用类型 传递给整个方法时,方法参数将是对同一对象的新引用,除非您使用{{ 1}}关键字

ref

因此...

使用以下代码调用public class A {} public class B { public void DoStuff(A a) // <--- "a" is a new reference of type A { a = new A(); } }

DoStuff

...会将A a = null; DoStuff(a); 类型的空引用赋予A。也就是说,您不会使用方法调用期间给出的引用,但是使用参数,因此,您不会更新源引用以指向新对象。

否则,您需要在方法签名中以及在某处调用它时使用DoStuff关键字:

ref