【问题标题】:Why is a private field accessible and a private setter not accessible from a static method?为什么可以从静态方法访问私有字段而无法访问私有 setter?
【发布时间】:2023-03-14 17:51:01
【问题描述】:

以下给我一个编译器错误:

    private ObservableEventListener Listener { get; private set; }

    public static void Register()
    {
        Log.Listener = new ObservableEventListener();
        Log.Listener.EnableEvents(Log, EventLevel.LogAlways, EventKeywords.None); 
    }

错误 26“MyEventSource.Listener.set”访问器的可访问性修饰符必须比属性或索引器“MyEventSource.Listener”更严格

但这编译得很好:

    private ObservableEventListener Listener;

    public static void Register()
    {
        Log.Listener = new ObservableEventListener();
        Log.Listener.EnableEvents(Log, EventLevel.LogAlways, EventKeywords.None);

    }

似乎支持 setter 方法的安全性更高?总是有多余的代码/警告行..为什么这是一个错误?

【问题讨论】:

  • 您已经将Listener 声明为private,因此setter 上的private 是多余的。删除它。
  • 你试过没有set上的“私人”吗?它已经是一个私有成员,所以加倍条件不会做任何事情,并且可能会根据给出的错误规则吓坏编译器。
  • 好的,但为什么会出错?总是有多余的代码行/警告..为什么这是一个错误?
  • @BradleyDotNET 是的,这应该是一个错误:这里的修饰符 必需 是“更具限制性”。私有并不比私有更严格,因此它失败了
  • @TMcKeown 这很容易解决:/warnaserror+ - 你去吧:现在他们都同样挑剔;p

标签: c#


【解决方案1】:

最终,这里唯一明智的答案是“因为语言设计者指定属性访问器的可访问性声明必须比属性本身更具限制性”。这就是为什么它是一个错误的全部原因。他们为什么选择那个...好吧,您可以尝试阅读带注释的规范,但是...嗯。

我想在private 属性上使用public 修饰符只是没有意义,所以很明显限制较少(更易于访问)是荒谬的;同样的限制是多余的:您添加关键字可能是为了做某事,但它不会产生任何结果 - 所以可能是一个错误。

【讨论】:

  • 嘿,你甚至不需要阅读规范。编译器错误说明了这一点。
【解决方案2】:

由于编译问题通常是这种情况,答案是因为spec 这么说!

第 10.7.2 节(强调我的)

  • 访问器修饰符必须声明比属性或索引器本身声明的可访问性更严格的可访问性。准确地说:
    • 如果属性或索引器具有声明的公共可访问性,则访问器修饰符可能是受保护的内部, 内部、受保护或私有。
    • 如果属性或索引器声明了受保护的内部可访问性,则访问器修饰符可以是内部的, 受保护或私有。
    • 如果属性或索引器的可访问性声明为 internal 或 protected,则访问器修饰符必须是私有的。
    • 如果属性或索引器声明可访问性为私有,则不得使用访问器修饰符。

【讨论】:

  • +1 用于查找规范的相关部分。再次 +1(如果可以的话)发现 这个确切的场景 列在规范中。
【解决方案3】:

您在 setter 上指定了 private,这通常没问题,除了您也创建了成员 private

private 没有比private 更严格,这违反了错误中引用的规则,即:

“MyEventSource.Listener.set”的可访问性修饰符 访问器必须比属性或索引器更严格 'MyEventSource.Listener'

也许语言设计者应该允许相同的限制,但他们没有,所以编译失败。

【讨论】:

  • 我选择这个错误是因为我同意你的 cmets !! =)
【解决方案4】:

在 getter 或 setter 上放置访问修饰符旨在允许您将其限制得比声明的整个属性更远。因此,获取私有属性然后尝试将其设置器设为私有是没有意义的,因为它已经是私有的。

正确使用,公共 getter,私人 setter:

public ObservableEventListener Listener { get; private set; }
^^ What you want BOTH Get/Setter to be         ^^ but you can make one more restrictive

错误:

private ObservableEventListener Listener { get; private set; }
^^ You want BOTH Get/Setter private             ^^ So what does this mean if you already made them private?

【讨论】:

    猜你喜欢
    • 2021-05-18
    • 2021-11-13
    • 2013-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多