在C# 8中使用接口的静态、内部和受保护访问修饰符

3

C# 8现在支持接口成员的访问修饰符,但它的使用方法让我感到困惑。看下面这个例子:

public interface IFoobar 
{   // these members are all valid
    protected string Protected { get; set; }
    internal string Internal { get; set; }
    static string Static { get; set; }
}

public class Foobar : IFoobar // <-- error, Internal and Protected members not implemented
{
    protected string Protected { get; set; }
    internal string Internal { get; set; }
    static string Static { get; set; } // only this one implements IFoobar
}

我的期望是Foobar完全实现IFoobar,但事实上只有Static实现了,其他的没有。
能否
  • 解释它们为什么行为不同(并且与C#8之前的接口成员不同)
  • 为这个接口中的每个修饰符给我一个用例?
谢谢。
[编辑]
我知道使用显式接口实现将会实现这些成员,但对于C# 8之前的接口成员,这并不是唯一的方式。为什么这些新成员不同?

1
看起来你需要显式实现这些成员。string IFoobar.Protected {get;set;} - Jonathon Chase
你能提供一下你得到这个例子的来源链接吗? - Christopher
我在8.0中找到的接口唯一变化是它们现在可以携带函数的默认代码:https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#default-interface-methods | 我没有发现任何关于访问修饰符的信息。如果这是一个问题,那么它比8.0更旧。 - Christopher
@Christopher 确保你使用针对 C#8 的环境进行尝试。 - Jonathon Chase
@Christopher 是的,那是因为Fiddler中的编译器设置为.NET v4.7.2。将其更改为.NET Core 3即可解决问题。 - Maurits Moeys
显示剩余6条评论
1个回答

5
我知道使用显式接口实现将实现成员,但对于早期的C# 8界面成员来说,这并不是唯一的方法。为什么新成员与以前的成员不同呢? 看起来这是有意设计的。以下是相关文本:
隐式实现非公共接口成员 我们是否允许隐式实现非公共接口成员?如果是,实现方法的可访问性需要满足什么要求?一些选项: 必须是公共的 必须具有完全相同的可访问性 必须至少具有相同或更高的可访问性
结论 目前,让我们简单地不允许它。只有公共接口成员可以被隐式实现(且只能由公共成员实现)。我们可以在思考中放松。
显然,带有访问修饰符的接口方法不会完全按照以前版本接口成员的规则进行操作,因为那些只能是公共的。
关于为什么会是这样,这是设计者的问题。LDM中的措辞并不像这是铁板钉钉的规定。因此也许将来会允许隐式实现访问修饰成员。
目前,实现此接口的方法是显式地这样做:
public interface IFoobar
{   // these members are all valid
    protected string Protected { get; set; }
    internal string Internal { get; set; }
    static string Static { get; set; }
}

public class Foobar : IFoobar
{
    string IFoobar.Protected {get;set;}
    string IFoobar.Internal {get;set;}
}

2
他们似乎非常清楚任何隐含的东西有多危险。你可以随时稍后添加隐含的内容,但是你永远无法删除它。 - Christopher
谢谢你的解释。虽然从概念上讲,我还没有学到很多关于为什么会是这样的知识,但从技术上讲,你已经回答了我问题的每一个部分。干杯! - Maurits Moeys
@MauritsMoeys 最终,我认为这主要是为了允许在不破坏所有当前实现者的情况下更改接口。额外的修饰符存在是为了简化那些默认实现在潜在接口层次结构上的实现。至少,这是我对它的最佳猜测。如果这是更容易或更可怕的选项之一,那么这是我打算仅使用的功能。 - Jonathon Chase

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