Why is a local function not always hidden in C#7?

前端 未结 4 767
谎友^
谎友^ 2021-01-03 21:43

What I am showing below, is rather a theoretical question. But I am interested in how the new C#7 compiler works and resolves local functions.

In C#7

4条回答
  •  心在旅途
    2021-01-03 22:39

    To expand a bit on v-andrew's answer, it is indeed analogous to having two variables with the same name. Consider that the following is allowed:

    void Main()
    {
        {
            void Main()
            {
                Console.WriteLine("Hello!");
            }
            Main();
        }
        {
            void Main()
            {
                Console.WriteLine("GoodBye!");
            }
            Main();
        }
    }
    

    Here we've two scopes and so we can have two local functions of the same name in the same method.

    Also to combine v-andrew's answer and your question, note that you can (and always could) have a variable called Main inside Main() but you can't have both a variable and a local function of the same name in the same scope either.

    On the other hand, you can't overload locals like you can members by having different parameters.

    Really, it's all closer to the existing rules for locals than the existing rules for methods. Indeed, it's the same rules. Consider you can't do:

    void Main()
    {
        {
            void Main()
            {
                int Main = 3;
                Console.WriteLine(Main);
            }
            Main();
        }
    }
    

    I thought, each inner Main() would have a local scope and is hidden outside.

    It is, but the scope includes the name of the local function. C.f. that you can't redefine a variable name from a for, foreach or using inside the its scope.

    Meanwhile, I think it is a compiler bug.

    It's a compiler feature.

    That means, removing the L from MainL should not harm because the compiler already renames it in a unique way, it should result in IL code like.

    That means it's possible to introduce a bug into the compiler where the code you have in your question would work. That would be in violation to the C# rules for names of locals.

    it is confusing in C#, but logical in C++

    It blocks something that has been known as a source of mistakes for some time. Likewise in C# you are not allowed to use integer values with if() and you have to explicitly fall-through in switch statements. All of these are changes that C# made to how it compares to C++ in the very beginning and all of them remove some convenience, but all of them are things that people really had found caused bugs and often prohibited in coding conventions.

提交回复
热议问题