我知道这段代码不好,也许这是一个愚蠢的问题,但有人可以解释一下为什么它会以这种方式运作吗?
我有这个简单的课程
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);
一切都会好的。但为什么我的第一次实施不起作用? 如果有人解释我,我会很感激。
答案 0 :(得分:3)
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表达式中,您只是说c
和model
指向相同的引用。然后你正在改变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);