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

Work out how "nameof" interacts with "this" #931

Open
jskeet opened this issue Sep 13, 2023 · 2 comments
Open

Work out how "nameof" interacts with "this" #931

jskeet opened this issue Sep 13, 2023 · 2 comments
Assignees
Labels
type: bug The Standard does not describe the language as intended or implemented
Milestone

Comments

@jskeet
Copy link
Contributor

jskeet commented Sep 13, 2023

Originally reported on #926.

Some comments from @KalleOlaviNiemitalo

A surprising interaction with nameof:

struct S {
    int i;
    
    void M() {
        string N() {
            return nameof(this);  // error CS1673
        }

        string O() {
            return nameof(this.i);  // error CS1673
        }

        string P() {
            return nameof(i);  // OK, returns "i"
        }
    }
}

To be checked:

  • nameof(this) in a default parameter or in an attribute argument (thus not in the function body) in a local or anonymous function in a struct
using System;
class DAttribute : Attribute {
    public DAttribute(string s) {}
}
struct S {
    int j;
    void LeA() {
        // OK
        Action<int> a = ([D(nameof(this.j))] int i) => {};
    }
    void LeD() {
        // error CS1065, default value not allowed
        Action<string> action = (string s = nameof(this.j)) => {};
    }
    void LfA() {
        // OK
        void F([D(nameof(this.j))] int i) {}
    }
    void LfD() {
        // error CS1673, cannot access this in local function
        void F(string s = nameof(this.j)) {}
    }
}

That seems pretty inconsistent. Why is nameof(this.j) allowed in an attribute argument in the parameter list, but not in a default parameter value? Is that what the standard should specify?

Expression trees seem to allow neither attributes nor default values, so the behaviour is more consistent for them:

using System;
using System.Linq.Expressions;
class DAttribute : Attribute {
    public DAttribute(string s) {}
}
struct S {
    int j;
    void ExA() {
        // error CS8972, attribute not allowed in expression tree
        Expression<Func<string, string>> e = ([D(nameof(this.j))] string s) => "";
    }
    void ExD() {
        // error CS1065, default value not allowed in expression tree
        Expression<Func<string, string>> e = (string s = nameof(this.j)) => "";
    }
    void ExR() {
        // error CS1673, lambda expression in struct cannot access this
        Expression<Func<string, string>> e = (string s) => nameof(this.j);
    }
}
@jskeet jskeet added the type: bug The Standard does not describe the language as intended or implemented label Sep 13, 2023
@jskeet jskeet added this to the C# 8.0 milestone Sep 13, 2023
@BillWagner
Copy link
Member

@jskeet As you work on nameof behavior, be aware that here be (generally harmless) dragons. The behavior of nameof is one of the places where the newer compiler doesn't perfectly match older implementations wheh the LangVersion is set to an older value.

See here: dotnet/docs#36980 (comment)

@jskeet
Copy link
Contributor Author

jskeet commented Sep 13, 2023

@BillWagner: Good to know, thanks. Not expecting to work on nameof for a while though :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug The Standard does not describe the language as intended or implemented
Projects
None yet
Development

No branches or pull requests

2 participants