成员访问修饰符对于 nameof() 有什么影响?

4

我对nameof()运算符有些困惑。例如,我不能在另一个类中使用类的私有字段来使用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
    }
}
3个回答

6
private等访问修饰符的目的是隐藏实现细节,它们的作用是说"不,你不需要知道这个。这是实现细节"。这就是为什么nameof不能访问私有属性的原因。无论你在哪个类中,该类都不应了解其他类的实现细节。
静态与非静态是不同的。它的目的不是隐藏你不需要知道的东西。它的目的只是区分属于类实例和类本身的成员。你想要的只是该成员的名称,它不需要创建任何实例,那么为什么要禁止你呢?注意,成员是可访问的,也就是说,这不是你不应该知道的东西。

是的,“目的”是关键词! - Rekshino

1

A 中的字段 X 是私有的。门是锁着的,无论你怎么做都无法访问它。

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

访问修饰符 (C# 编程指南)

所有类型和类型成员都有一个可访问性级别,它控制它们是否可以从您的程序集或其他程序集中的其他代码中使用。在声明类型或成员时,您可以使用以下访问修饰符来指定其可访问性:

and

  • public 表示该类型或成员可以被同一程序集中的任何其他代码或引用它的另一个程序集中的代码访问。

  • private 表示该类型或成员只能被同一类或结构中的代码访问。

  • protected 表示该类型或成员只能被同一类中的代码或从该类派生的类中的代码访问。internal 表示该类型或成员可以被同一程序集中的任何代码访问,但不能从另一个程序集中访问。

  • protected internal 表示该类型或成员可以被声明它的程序集中的任何代码访问,或者在另一个程序集中的派生类中访问。

  • private protected 表示该类型或成员只能被声明它的程序集中的代码访问,或者是从该类派生的类型中的代码访问。


1
但是 nameof(x) 是否访问成员 x 呢?它肯定不会对其进行评估。为了完整起见,您应该添加一个详细的来源。 - Pablo H

0

虽然不是直接回答你的问题,但我通常会使用一个静态帮助类来解决这个问题:

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

    private string X { get; }
}

然后使用

A.Properties.X

这可能会有点啰嗦,但仍然可以有效地启用重构工具。


1
我认为为了通过反射调用而暴露名称是错误的。假设您不再需要私有成员...那么您将如何更新属性?当私有字符串是您程序集的内部细节时,您可以将其作为内部属性,并且 nameof 就可以正常工作。 - Wouter
@Wouter 我同意,但有时候ORM或其他框架会假设你拥有所有公共成员。对于一个发布的库,我肯定不会这样做。 - kͩeͣmͮpͥ ͩ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接