简体   繁体   中英

Why does Unity throw error CS0136 here while Visual Studio 2019 doesn't?

Suppose you have this code in Unity (adapted from another SO question ):

public class Test : MonoBehaviour {
    void Start() {
        int x = 0;
        void foo() {
            int x = 0;
            x = 1;
            Debug.Log(x);
        }
    }
}

In Visual Studio 2019, the compiler happily accepts this code, which makes sense given the explanation provided at the SO answer.

However Unity throws error CS0136 , with the message:

error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter

This seems to reference local scopes (not local functions), which indeed cannot redefine variables declared in the containing scope.

Local functions do seem to work in Unity (I can call foo after changing the variable names and get the expected Debug.Log output), so I'm wondering why this difference in compilers exists (and if there's acknowledgement/explanation for that difference somewhere in the docs).

Why does Unity throw an error here?

Unity Player Settings are set to Mono for Scripting backend and .NET Standard 2.0 for API compatibility (if that makes a difference).

EDIT: Unity version is 2019.3.0f6.

This seems to be the result of how Unity creates the csproj file, specifically the Language version it sets, and the mismatch between C# 8 and 7.3.

As a reference, this feature (hiding variable names in local functions) was introduced in C# 8. Here's the github link to the change. As to why the Unity project uses C# 8, my best guess is below.

If you open up the csproj file created by Unity, you'll find

<PropertyGroup>
  <LangVersion>latest</LangVersion>
</PropertyGroup>

as well as a target to 4.7.1 (regardless of what your Unity project settings are)

<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>

and a defined constant: CSHARP_7_3_OR_NEWER , which is a Unity constant

From the C# docs on language versions, you can find that while .NET Standard 2.0 defaults to C# 7.3, the above <LangVersion> value seems to imply that the language version used in VS will be the latest one it has access to. Here's the relevant bit from the above link:

latest - The compiler accepts syntax from the latest released version of the compiler (including minor version).

So in the end, it looks like if you've installed a compiler that supports C# 8, the Unity project will be setup in a way that allows that, even though it looks like internally, Unity is still using C# 7.3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM