Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我不能从闭包中修改变量,为什么?_C#_Dynamic_Lambda_Closures - Fatal编程技术网

C# 我不能从闭包中修改变量,为什么?

C# 我不能从闭包中修改变量,为什么?,c#,dynamic,lambda,closures,C#,Dynamic,Lambda,Closures,我想看看是否可以用javascript方式编写一些c#代码,但我得到了一个意想不到的行为。我知道c#没有坏,但我不明白什么是错的,为什么它没有做我认为应该做的事情 代码: class Program { static void Main(string[] args) { var person = CreatePerson(new{ FirstName = "Lucas", LastName = "Ontivero",

我想看看是否可以用javascript方式编写一些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
但我想

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

为什么名字不改变?

它确实改变了。。。但是
FullName
没有。它在
CreatePerson
中计算,并存储为
字符串
,而不是稍后计算为字符串的属性


您可以使用lambdas导致计算延迟,就像您在
SetFirstName

中所做的那样,它为您提供了第一个全名赋值。
您需要重新分配全名

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

SetFirstName
Function

上,有没有办法获取Person类的代码?@EtherDragon:没有类,
CreatePerson
返回一个匿名类型的实例。我认为这里的关键是返回一个匿名类型,匿名类型总是不可变的。当
new
创建匿名类型实例时,您所做的任何操作(反射黑客可能除外)都不会修改您在该实例中输入的值。此外,通过设置
firstName
,他设置的是局部变量
firstName
而不是字段
firstName
?@sirpontor:他设置的是捕获的变量
firstName
(闭包中使用的变量不是局部变量)。而字段
FirstName
是对象初始化时的
FirstName
的副本。@BenVoigt我需要学习C#中的这种新型东西。