C# 中的 public 嵌套 class 和私有嵌套 class 有什么区别

What is the difference between a public nested class and private nested class in C#

在 C# 中,public 嵌套 class 和私有嵌套 class 之间有什么区别(如果有的话)?你会在什么时候使用其中一节经文?

据我所知,从嵌套的 class 以及任何外部 classes 的角度来看,它们具有相同的可访问性。

void Main()
{
    Item i = new Item();
    i.DoSomething();

    GizmoBuilder gb = new GizmoBuilder();//class not accessible
    WidgetBuilder wb = new WidgetBuilder();//class not accessible
}

public class Item
{
    public int Id { get; set; }

    private string ItemName { get; set;}

    public void DoSomething()
    {
        GizmoBuilder g = new GizmoBuilder();
        g.BuildGizmo();
        Console.WriteLine(g.BuildId);
        Console.WriteLine(g.Name);//g.Name not accessible

        WidgetBuilder w = new WidgetBuilder();
        w.BuildWidget();
        Console.WriteLine(w.BuildId);
        Console.WriteLine(w.Name);//g.Name not accessible
    }

    public class GizmoBuilder
    {
        public int BuildId { get; set; }

        private string Name { get; set;}

        public void BuildGizmo()
        {           
            Builder b = new Builder();
            b.Build();

            Console.WriteLine("Building Gizmo");
        }
    }

    private class WidgetBuilder
    {
        public int BuildId { get; set; }

        private string Name { get; set;}

        public void BuildWidget()
        {
            Builder b = new Builder();
            b.Build();

            Console.WriteLine("Building Widget");
        }
    }

    private class Builder
    {
        public void Build()
        {
            Console.WriteLine("Building");
        }
    }
}

这不会编译。这就是区别。

public class C {
    private class D {  }

    //  Nobody outside C can know about D, so this is forbidden. 
    public D Property { get; set; }

    //  But this is OK, because object is public. 
    private D _d = new D();
    public Object Property2 => _d;
}

将私有 class 的实例传递给 Console.WriteLine() 与访问无关;它看到对 object (public) 的引用并在其上调用 ToString() (public)。

As far as I can tell they have the same accessibility from the view of the class they are nested in as well as from any external classes.

它们嵌套在 class 中,这是事实,但是,如果嵌套的 class 是私有的,则没有外部 class 可以访问它。

一个简化的例子:

public class Foo
{
    public class Bar { }

    private class Baz { }
}

使用它们:

var bar = new Bar();
var nestedBar = new Foo.Bar();
var nestedBaz = new Foo.Baz();

GizmoBuilder gb = new GizmoBuilder() 您声称 "class [is] not accessible",但这是不正确的。实际的编译器错误,属于以上三个中的第一行,是:

CS0246: The type or namespace name `Bar' could not be found. Are you missing an assembly reference?

那是因为您必须在包含 class 的名称前加上前缀,如第二行所示。那行得通,因为 Foo.Bar 是 public.

第三行,访问私有嵌套class,显示:

CS0122: `Foo.Baz' is inaccessible due to its protection level

这就是你的不同之处。您只能从 Foo.

内部使用后者 (Foo.Baz)

如果嵌套的 class 是 public 那么您可以从 任何地方 实例化它并访问封闭的 class.

如果嵌套的 class 是私有的,您只能从封闭的 class.

实例化它

当您需要封闭的 class 成为可以创建该新类型的 只有 class 时,这很有用。例如:

public interface INestedClass 
{
    double ComplexCalculation(double input);
}

public class Test 
{
    public INestedClass GenerateInstance() 
    {
        return new SubClass();
    }

    private class SubClass : INestedClass
    {
        public double ComplexCalculation(double input) 
        {
            return input*5;
        }
    }
}

在封闭的 class 范围之外,您将无法执行此操作,因为嵌套的 class 是私有的:

var subClassInstance = new Test.SubClass();