【问题标题】:I cannot modify a variable from a closure, why?我无法从闭包中修改变量,为什么?
【发布时间】:2012-05-23 03:42:26
【问题描述】:

我想看看我是否可以以 javascript-fashion 的方式编写一些 c# 代码,但我得到了一个意想不到的行为。我知道 c# 没有坏,但我不明白什么是错的,为什么它没有做我认为应该做的事情。

代码

class Program
{
    static void Main(string[] args)
    {
        var person = CreatePerson(new{
            FirstName = "Lucas",
            LastName = "Ontivero",
            Age = 34
        });

        Console.WriteLine("Name....... : {0}", person.FullName);
        Console.WriteLine("IsJuvenile. : {0}", person.IsJuvenile);

        person.SetFirstName("Pablo");
        Console.WriteLine("Name....... : {0}", person.FullName);

        Console.ReadKey();
    }

    static private dynamic CreatePerson(dynamic cfg)
    {
        string firstName = cfg.FirstName;
        string lastName = cfg.LastName;
        var age = cfg.Age;

        return new{
            FullName = string.Format("{0} {1}", firstName, lastName),
            FirstName = firstName,
            LastName = lastName,
            SetFirstName = new Action<string>(fn => firstName= fn),
            SetLastName = new Action<string>(ln => lastName = ln),
            IsJuvenile = age < 18 
        };
    }
}

输出

Name....... : Lucas Ontivero
IsJuvenile. : False
Name....... : Lucas Ontivero

但我期待

Name....... : Lucas Ontivero
IsJuvenile. : False
Name....... : Pablo Ontivero

为什么名字不变?

【问题讨论】:

  • 有什么方法可以获取 Person 类的代码?
  • @EtherDragon:没有类,CreatePerson返回一个匿名类型的实例。
  • 我认为这里的关键是您返回的是匿名类型,而匿名类型始终是不可变的。当您 new 启动它时,您所做的任何事情(反射黑客可能除外)都不会修改您放入该匿名类型实例的值。

标签: c# dynamic lambda closures


【解决方案1】:

确实...但FullName 没有。它在CreatePerson 内部计算并存储为string,而不是稍后评估为字符串的属性。

您可以使用 lambda 来导致延迟评估,就像使用 SetFirstName 一样。

【讨论】:

  • 另外,通过设置firstName,他是否设置了局部变量firstName而不是字段FirstName
  • @SirPentor:他正在设置捕获的变量firstName(闭包中使用的变量不是本地变量)。而FirstName 字段是对象初始化时firstName 的副本。
  • @BenVoigt 我需要了解 C# 中的这些新奇东西。
【解决方案2】:

它会给你全名的第一个任务。
您需要重新分配 FullName

FullName = string.Format("{0} {1}", firstName, lastName)

开启SetFirstName功能

【讨论】:

    猜你喜欢
    • 2020-09-04
    • 2017-02-21
    • 2011-11-24
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-02-04
    • 1970-01-01
    • 2021-09-15
    相关资源
    最近更新 更多