为什么私有字段可以被访问而私有 Setter 方法在静态方法中不可访问?

3
以下代码会导致编译错误:
    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方法周围有更多的安全性?总是有冗余的代码行/警告..为什么这是一个错误?


8
дҪ е·Із»Ҹе°ҶListenerеЈ°жҳҺдёәз§Ғжңүзҡ„пјҢеӣ жӯӨеңЁsetterдёҠзҡ„privateжҳҜеӨҡдҪҷзҡ„гҖӮиҜ·е°Ҷе…¶еҲ йҷӨгҖӮ - Gjeltema
private不比private更严格,所以这是一个错误。虽然它本应该不是一个错误,但编译器很挑剔。 - BradleyDotNET
5
@BradleyDotNET 是的,这应该是一个错误:修饰符在此处“必须”比原来更严格限制。private 不比 private 更严格,因此它失败了。 - Marc Gravell
为什么对一个完全好的问题进行负评? - T McKeown
5
很容易解决:/warnaserror+ - 就这样:现在它们都一样严格了;p - Marc Gravell
显示剩余5条评论
4个回答

6
最终,这里唯一合理的答案是“因为语言设计者规定了属性访问器的可访问性声明必须比属性本身更加严格”。这就是为什么会出现错误的全部原因。至于他们为什么选择这样做...嗯,你可以试着阅读注释规范,但是...无所谓。
我想,给私有属性添加public修饰符根本没有意义,因此显然更不严格(更容易访问)是无意义的;而同样严格则是多余的:你添加关键字的目的可能是要执行某些操作,但它将没有任何结果-所以可能出现错误。

2
哈哈,你甚至不需要阅读规范。编译器错误已经明确指出了。 - David Crowell

6
由于编译问题通常如此,答案是因为规范是这样规定的!
第10.7.2节(我强调)
  • 访问器修饰符必须声明比属性或索引器本身的声明可访问性更严格的可访问性。具体来说:
    • 如果属性或索引器的声明可访问性为public,则访问器修饰符可以是protected internal、internal、protected或private。
    • 如果属性或索引器的声明可访问性为protected internal,则访问器修饰符可以是internal、protected或private。
    • 如果属性或索引器的声明可访问性为internal或protected,则访问器修饰符必须是private。
    • 如果属性或索引器的声明可访问性为private,则不能使用访问器修饰符。

2
如果能找到规范中相关的部分,加1分。如果能找到规范中列出了这个确切的场景,再加1分(如果可以的话)。 - BradleyDotNET

5
您在setter上指定了private,这通常没有问题,但您也将成员设为private。 private并不比private更严格,这违反了错误中引用的规则,即:
“MyEventSource.Listener.set”访问器的可访问性修饰符必须比属性或索引器“ MyEventSource.Listener”更严格。
也许语言设计者应该允许相等的限制性,但他们没有这样做,所以编译失败。

我选择了这个错误,因为我同意你的评论!! =) - T McKeown

2
在getter或setter上放置访问修饰符是为了允许您进一步限制它,而不仅仅是声明整个属性。因此,尝试将私有属性的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?

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