在Action <t>委托中创建类

时间:2017-02-14 13:55:34

标签: c#

我知道这段代码不好,也许这是一个愚蠢的问题,但有人可以解释一下为什么它会以这种方式运作吗?

我有这个简单的课程

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

我有Action委托的下一个方法

private Customer GetCustomer(Action<Customer> action)
{
    var model = new Customer { Name = "Name 1" };
    action?.Invoke(model);

    return model;
}

然后我用delegate执行这个方法并写入console model.Name

var model = GetCustomer(c => c = new Customer { Name = "Name 2" });
Console.WriteLine(model.Name);

我希望得到&#34;名称2&#34;。但我得到了#1;名称1&#34; - 这是在方法内定义的类的值。我理解为了得到我想要的东西 - 我可以用这种方式编写代码:

var model = GetCustomer(c => c.Name = "Name 2");
Console.WriteLine(model.Name);

一切都会好的。但为什么我的第一次实施不起作用? 如果有人解释我,我会很感激。

4 个答案:

答案 0 :(得分:3)

lambda中的

c仅分配给参数,而不是将其分配回model中的GetCustomer

答案 1 :(得分:1)

您案例中的Lambda表达式编译成一个方法 这是相同的,为什么此代码不会更改c.Name

// code below is equivalent of
// c => c = new Customer { Name = "Name 2" }
private void Foo(Customer c)
{
    // c will be changed inside method,
    // but will remain unchanged outside it
    c = new Customer { Name = "Name 2" };
}

答案 2 :(得分:0)

var model = GetCustomer(c => c.Name = "Name 2");

而不是:

var model = GetCustomer(c => c = new Customer { Name = "Name 2" });

为什么呢?因为您希望对在新函数中传输的同一实例进行更改(实现委托)。如果您在新功能(Customer)中创建c的新实例,那么它会对Customer的新实例进行更改,这些更改在c时无效结束。

相同here,但List

答案 3 :(得分:0)

在lambda表达式中,您只是说cmodel指向相同的引用。然后你正在改变c的引用。最后model仍然引用前一个实例。这是您尝试执行的操作的等效代码:

var model = new Customer { Name = "Name 1" };
var c = model;
c = new Customer { Name = "Name 2" };

但是,model.Name仍为Name1

您可以更改代码,就像要更改其中一个hte属性一样:

 var model = GetCustomer(c => c.Name = "Name2");
 Console.WriteLine(model.Name);