内部班的公开和内部成员?


70

好的,所以这可能是一个愚蠢的问题,并且肯定有很明显的答案,但是我很好奇我是否错过了这里的任何细微之处。

publicinternal类中internal声明的成员与在类中声明的成员之间在可见性/可用性方面是否有区别internal

即之间

internal class Foo
{
    public void Bar()
    {
    }
}

internal class Foo
{
    internal void Bar()
    {
    }
}

如果将方法声明为public和并且virtual,然后在派生类中覆盖它,则public使用此修饰符的原因很明显。但是,这是唯一的情况吗...我还缺少其他东西吗?


4
如果您将该方法声明为public且也为虚拟方法,然后将其覆盖为public meeeep的派生类:不允许您增加可见性,只能以相反的方式:您可以创建内部(甚至嵌套和私有)公共类的派生类
springy76

5
Google员工请注意:这个几乎重复的问题包含另一个特别出色的答案。
迈克尔·理查森

Answers:


62

考虑这种情况:

public interface IBar { void Bar(); }
internal class C : IBar
{
    public void Bar() { }
}

在这里,C.Bar不能标记为内部。这样做是一个错误,因为D.GetBar()的调用者可以访问C.Bar:

public class D
{
    public static IBar GetBar() { return new C(); } 
}

1
谢谢埃里克,这是另一个很好的例子。因此,有效的接口实现和类继承是允许在类中使用publicorinternal修饰符的原因internal。在其他情况下,它们看起来是等效的。
Noldorin

9
埃里克(Eric)在以下位置也回答了几乎相同的问题:stackoverflow.com/a/9302642/398015他的帖子中还有其他一些细节,这些细节为上述答案增加了可观的内容。
克里斯(Chris

44

一个public成员还只是internal在当internal类。

从MSDN

成员的可访问性永远不能大于其包含类型的可访问性。例如,以内部类型声明的公共方法仅具有内部可访问性

这样想,我将访问public...。我看不到的课程?:)

在这种情况下,埃里克(Eric)的回答非常重要,如果它是通过接口公开的,而不是通过接口公开的,那么它的确会有所作为,这取决于您与所处理的成员是否处于这种情况。


是的,除了埃里克指出的情况(以及我最初的问题中的那个)以外,这确实是我的想法。
Noldorin

使用反射时,也会有所不同。默认的无参数方法(如Type.GetMethods())仅返回公共成员。内部类内部的public方法仍然知道它是公共的。
springy76 2012年

2
“成员的可访问性永远不能大于其包含类型的可访问性。” 同时保持对于某些情况属实,一个public一个的构件private类显然比一个更宽范围privatea的部件private类(前者为项目宽,只有后者是类)。
Deanna

@Deanna是的...但是这不会使前一个语句错误,您正在将同等容器而不是容器进行比较-可访问的事物不会改变,因为您无法从私有类外部访问公共成员容器。
尼克·克拉弗

2

只是面对另一个例子那里这两个,从XAML在WPF使用时之间的差异。

XAML:

<Button Tag="{x:Static vm:Foo+Bar.e1}" />

带有internalenum的代码可以成功编译:

internal class Foo
{
    internal enum Bar
    {
        e1,
        e2,
    }
}

但是令人惊讶地将其更改为会public导致错误:

internal class Foo
{
    public enum Bar
    {
        e1,
        e2,
    }
}

最后一个示例产生编译错误:

错误MC3064:在标记内只能使用公共或内部类。“酒吧”类型不是公开的也不是内部的。

不幸的是,public在这种情况下我无法解释问题所在。我的猜测是“仅仅因为WPF那样工作”。只需更改嵌套类的修饰符internal即可摆脱错误。


这次真是万分感谢!我永远猜不到我的XAML出了什么问题
torvin

1

public一个成员的internal类可以重写public的成员public基类的,因此,是一个小更暴露...如果是间接的。


1

关于反思,成员是否公开很重要:

例如,您甚至可以将嵌套的私有类传递给WPF绑定,并且绑定将像往常一样对公共属性起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.