Why member access modifier does matter for nameof()?
Asked Answered
G

3

6

I'm a little bit confused with nameof() operator. So for example I can't use class's private fields in nameof() in another class, but I can use public non static fields using non static property, so I don't need instantiated object.

Is it consistently? Why member access modifier does matter for nameof()?

class A
{
    private int X;
    public int Y;
    public A()
    {
        var x = nameof(A.X);//OK
        var y = nameof(A.Y);//OK
    }
}
class B
{
    public B()
    {
        var x = nameof(A.X);//Compilation error
        var y = nameof(A.Y);//OK
    }
}
Gauge answered 21/6, 2018 at 9:3 Comment(0)
S
8

The purpose of access modifiers like private is to hide the implementation details. They are saying "Nope, you don't need to know this. This is implementation detail". That's why nameof is not allowed to access private properties. Whatever class you are in, that class should not know about the implementation details of some other class.

Static vs non-static is different. Its purpose is not to hide something that you don't need to know about. Its purpose is just to distinguish between members that belongs to instances of the class and members that belongs to the class itself. All you want here is just the name of that member, which requires no instances to be created, so why disallow you? Note that the member is accessible i.e. it's not something you shouldn't know about.

Sura answered 21/6, 2018 at 9:9 Comment(1)
Yes, "the purpose" is the key word!Gauge
S
2

Not a direct answer to your question, but I usually get around this but using a static helper class:

class A
{
    public static class Properties
    {
        public const string X = nameof(A.X);
    }

    private string X { get; }
}

Then using

A.Properties.X

It's a little bit more verbose, but still enables refactoring tools to work effectively.

Seminary answered 21/6, 2018 at 9:34 Comment(2)
I think exposing the name in order to invoke it by reflection is wrong. Suppose you don't need the private member anymore... how are you going to update your Properties? When the private string is an internal detail to your assembly you could make it an internal property and nameof just works.Premiere
@Premiere I agree, but sometimes an ORM or other framework assumes you have all public members. I certainly wouldn't do this for a published library.Richelieu
R
1

Field X in class A is private. door is locked, you cant access it no matter what you do.

This is not a nameof problem, its Access Modifier problem

Access Modifiers (C# Programming Guide)

All types and type members have an accessibility level, which controls whether they can be used from other code in your assembly or other assemblies. You can use the following access modifiers to specify the accessibility of a type or member when you declare it:

and

  • public The type or member can be accessed by any other code in the same assembly or another assembly that references it.

  • private The type or member can be accessed only by code in the same class or struct.

  • protected The type or member can be accessed only by code in the same class, or in a class that is derived from that class. internal The type or member can be accessed by any code in the same assembly, but not from another assembly.

  • protected internal The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly.

  • private protected The type or member can be accessed only within its declaring assembly, by code in the same class or in a type that is derived from that class.

Rashad answered 21/6, 2018 at 9:8 Comment(1)
But does nameof(x) access member x? It certainly does not evaluate it. You should add a source for this detail, for completeness sake.Caduceus

© 2022 - 2024 — McMap. All rights reserved.