Are there any good reasons why closing is not immutable in C #?

I went through all this in my head, and I can't figure out why the reason for closing C # is volatile. This is just a good way to get unforeseen consequences if you don’t know what exactly is happening.

Perhaps someone who is a little knowledgeable might shed some light on why C # designers would allow the state to change the closure?

Example:

var foo = "hello";
Action bar = () => Console.WriteLine(foo);
bar();
foo = "goodbye";
bar();

This will print “hello” for the first call, but the external state will change for the second call by typing “goodbye”. The close status has been updated to reflect changes to the local variable.

+5
source share
6 answers

# JavaScript, O'Caml Haskell . , , . , , O'Caml Haskell, , ; , , , # JavaScript.

+8

. .

, , , #... .

: , - ECMA, . Microsoft .

+3

. - , , , - .

, , .

+2

, # . .Net ( ICloneable ..), " ", "" foo :

class Foo
{
    public string Text;
}    
var foo = new Foo();
foo.Text = "Hello";
Action bar = () => Console.WriteLine(foo.Text);
bar();
foo.Text = "goodbye";
bar();

, .

+1

, , . - :

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    public string foo;

    public void <Main>b__0()
    {
        Console.WriteLine(this.foo);
    }
}

, . , foo , , .

, foo , , . , , :

var foo = "hello";
Action bar = [readonly foo]() => Console.WriteLine(foo);
bar();
foo = "goodbye";
bar();

, , , foo readonly, :

[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    public readonly string foo;

    public <>c__DisplayClass1(string foo)
    {
        this.foo = foo;
    }

    public void <Main>b__0()
    {
        Console.WriteLine(this.foo);
    }
}

, , .

0

- , #, : " (Java) (#)?"

Mutable closures . :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClosureTest
{
    class Program
    {   
        static void Main(string[] args)
        {
            string userFilter = "C";            
            IEnumerable<string> query = (from m in typeof(String).GetMethods()
                                         where m.Name.StartsWith(userFilter)
                                         select m.Name.ToString()).Distinct();

            while(userFilter.ToLower() != "q")
            {
                DiplayStringMethods(query, userFilter);
                userFilter = GetNewFilter();
            }
        }

        static void DiplayStringMethods(IEnumerable<string> methodNames, string userFilter)
        {
            Console.WriteLine("Here are all of the String methods starting with the letter \"{0}\":", userFilter);
            Console.WriteLine();

            foreach (string methodName in methodNames)
                Console.WriteLine("  * {0}", methodName);
        }

        static string GetNewFilter()
        {
            Console.WriteLine();
            Console.Write("Enter a new starting letter (type \"Q\" to quit): ");
            ConsoleKeyInfo cki = Console.ReadKey();
            Console.WriteLine();
            return cki.Key.ToString();
        }
    }
}

, , . :

        string userFilter = "C";
        string userFilter_copy = userFilter;
        IEnumerable<string> query = (from m in typeof(String).GetMethods()
                                     where m.Name.StartsWith(userFilter_copy)
                                     select m.Name.ToString()).Distinct();

, , userFilter .

Jon Skeet Java #.

0

All Articles