Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extended nameof scope works in C# 8? #36980

Closed
RajaniCode opened this issue Sep 6, 2023 · 4 comments
Closed

Extended nameof scope works in C# 8? #36980

RajaniCode opened this issue Sep 6, 2023 · 4 comments
Labels

Comments

@RajaniCode
Copy link

RajaniCode commented Sep 6, 2023

Extended nameof scope works in C# 8?

Please refer to the following output of the code snippet (provided below the output) running on Visual Studio 2022 Community Edition for Apple Silicon, MacBook Pro M1 Pro, macOS Ventura Version 13.5.2 (22G91).
NB:
The code snippet comments include compiler errors for features greater than C# 8 (C# 9, C# 10, and C# 11) only to find out if "extended nameof scope" works in C# 8?

Output
/**********************************************************************************************************************/
OS Information:
Platform: Unix
Version String: Unix 22.6.0.0
Version Information:
Major: 22
Minor: 6
Service Pack: ''
Environment.Version: 3.1.28
RuntimeInformation.FrameworkDescription: .NET Core 3.1.28

Extended nameof scope
nameof expression with a method parameter
/**********************************************************************************************************************/

Code Snippet
/**********************************************************************************************************************/

// <Nullable>enable</Nullable>
class NameOfExpression
{
    // Works in CS 8?
    [return: System.Diagnostics.CodeAnalysis.NotNullIfNotNull(nameof(url))]
    string? GetTopLevelDomainFromFullUrl(string? url) => url;

    // Works in CS 8?
    [ParameterString(nameof(msg))]
    public void Method(string msg)
    {
        // Error CS8400: Feature 'local function attributes' is not available in C# 8.0. Please use language version 9.0 or greater.
        // LocalFunction<string>(msg);
        // [ParameterString(nameof(T))]
        // void LocalFunction<T>(T param)
        // {
            // System.Console.WriteLine(param);
        // }

        System.Console.WriteLine(msg);

        // Error CS8400: Feature 'lambda attributes' is not available in C# 8.0. Please use language version 10.0 or greater.
        //  Error CS8400: Feature 'inferred delegate type' is not available in C# 8.0. Please use language version 10.0 or greater.
        // var lambdaExpression = ([ParameterString(nameof(aNumber))] int aNumber) => aNumber.ToString();
    }
}

// Custom Attribute
class ParameterStringAttribute : System.Attribute
{
    public ParameterStringAttribute(string msg) { }
}

class PatternMatchSpan
{
    public void Print()
    {
        // System.Console.WriteLine("Pattern match Span<char> or ReadOnlySpan<char> on a constant string: Span<char>");
        string contentLength = "Content-Length: 132";
        System.Span<char> span = contentLength.ToCharArray();
        System.Span<char> slice = span.Slice(16);
        // Error CS8400: Feature 'pattern matching ReadOnly/Span<char> on constant string' is not available in C# 8.0. Please use language version 11.0 or greater.
        // System.Console.WriteLine($"Pattern match Span<char>: {slice is "132"}");
        // System.Console.WriteLine("Pattern match Span<char> or ReadOnlySpan<char> on a constant string: ReadOnlySpan<char>");

        System.ReadOnlySpan<char> spanReadOnly = contentLength.ToCharArray();
        System.ReadOnlySpan<char> sliceReadOnly = spanReadOnly.Slice(16);
        // Error CS8400: Feature 'pattern matching ReadOnly/Span<char> on constant string' is not available in C# 8.0. Please use language version 11.0 or greater.
        // System.Console.WriteLine($"Pattern match ReadOnlySpan<char>: {sliceReadOnly is "132"}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Version
        /******************************************************************************/
        var os = System.Environment.OSVersion;
        System.Console.WriteLine("OS Information:");
        System.Console.WriteLine("Platform: {0:G}", os.Platform);
        System.Console.WriteLine("Version String: {0}", os.VersionString);
        System.Console.WriteLine("Version Information:");
        System.Console.WriteLine("   Major: {0}", os.Version.Major);
        System.Console.WriteLine("   Minor: {0}", os.Version.Minor);
        System.Console.WriteLine("Service Pack: '{0}'", os.ServicePack);

        // Environment.Version property returns the .NET runtime version for .NET 5+ and .NET Core 3.x
        // Not recommend for .NET Framework 4.5+
        System.Console.WriteLine($"Environment.Version: {System.Environment.Version}");
        // RuntimeInformation.FrameworkDescription property gets the name of the .NET installation on which an app is running
        // .NET 5+ and .NET Core 3.x // .NET Framework 4.7.1+ // Mono 5.10.1+
        System.Console.WriteLine($"RuntimeInformation.FrameworkDescription: {System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription}");
        System.Console.WriteLine();
        /******************************************************************************/

        System.Console.WriteLine("Extended nameof scope");
        NameOfExpression expressionNameOf = new NameOfExpression();
        expressionNameOf.Method("nameof expression with a method parameter");
        System.Console.WriteLine();

        //  Error CS8400: Feature 'target-typed object creation' is not available in C# 8.0. Please use language version 9.0 or greater.
        // PatternMatchSpan spanPatternMatch = new();
        PatternMatchSpan spanPatternMatch = new PatternMatchSpan();
        // System.Console.WriteLine("Pattern match Span<char> or ReadOnlySpan<char> on a constant string");
        spanPatternMatch.Print();
    }
}

/**********************************************************************************************************************/

@dotnet-bot dotnet-bot added the ⌚ Not Triaged Not triaged label Sep 6, 2023
@BillWagner
Copy link
Member

Hi @RajaniCode

Adding @jcouv and @333fred to make sure my analysis below is correct.

This is an instance where the results using the LangVersion element and the compiler bits for a given release are different. There are a very small number of instances where that's true. The extended nameof scope was implemented for C# 11. The parser in all compilers beginning with C# 11 resolve the symbol, so that small feature "works" even when the LangVersion switch is set to an earlier version.

My plan is to close this as not a docs issue, but I'll wait for others to weigh in.

@333fred
Copy link
Member

333fred commented Sep 7, 2023

@BillWagner is correct. LangVersion is something we make a best effort at enforcing in all scenarios, but there are some cases (this one among them) where we judge that the cost to implement and maintain the check is higher than the benefit that users will get from it.

@BillWagner
Copy link
Member

closing as by design

@dotnet-bot dotnet-bot removed the ⌚ Not Triaged Not triaged label Sep 7, 2023
@RajaniCode
Copy link
Author

RajaniCode commented Sep 11, 2023

Two cents: .NET legacy, more than a decade ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants