为什么成员访问修饰符对 nameof() 很重要?

Why member access modifier does matter for nameof()?

我对 nameof() 运算符有点困惑。例如,我不能在另一个 class 中使用 class 在 nameof() 中的私有字段,但我可以使用 publicstatic 字段 , 所以我不需要实例化对象。

是否始终如一?为什么成员访问修饰符对 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
    }
}

class A 中的字段 X 是私有的。门是锁着的,无论你做什么都进不去。

这不是 nameof 问题,而是 访问修饰符 问题

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:

  • 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.

private这样的访问修饰符的目的是隐藏实现细节。他们说 "Nope, you don't need to know this. This is implementation detail"。这就是为什么 nameof 不允许访问私有属性的原因。无论 class 你在哪个 class 不应该知道其他 class.

的实现细节

静态与非静态是不同的。它的目的不是隐藏你不需要知道的东西。它的目的只是区分属于 class 实例的成员和属于 class 本身的成员。您在这里只需要该成员的名称,不需要创建实例,那么为什么不允许您这样做呢?请注意,该成员是可访问的,即这不是您不应该知道的事情。

不是你问题的直接答案,但我通常会使用静态助手来解决这个问题 class:

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

    private string X { get; }
}

然后使用

A.Properties.X

它有点冗长,但仍然可以使重构工具有效地工作。