C#中公共嵌套类和私有嵌套类之间的区别是什么

时间:2017-06-01 20:31:45

标签: c# inner-classes

在C#中,公共嵌套类和私有嵌套类之间有什么区别?你什么时候用另一个经文?

据我所知,他们在类的视图中具有相同的可访问性,它们嵌套在任何外部类中。

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");
        }
    }
}

4 个答案:

答案 0 :(得分:6)

简化示例:

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(),您声称"类[is]无法访问",但这不正确。属于上述三行第一行的实际编译器错误是:

  

CS0246:类型或命名空间名称“Bar'无法找到。你错过了装配参考吗?

那是因为你必须在包含类的名称前加上前缀,如第二行所示。这是有效的,因为Foo.Bar是公开的。

访问私有嵌套类的第三行显示:

  

CS0122:`Foo.Baz'由于其保护级别而无法访问

所以你的区别就在于此。您只能在Foo.Baz内使用后者(Foo)。

答案 1 :(得分:3)

  

据我所知,他们在类的视图中具有相同的可访问性,它们嵌套在任何外部类中。

从嵌套的类中可以看出,如果嵌套类是私有的,则没有外部类可以访问它。

答案 2 :(得分:2)

如果嵌套类是公共的,那么您可以从任何地方实例化它,并且可以访问封闭类。

如果嵌套类是私有的,则只能从封闭类中实例化它。

当您需要将封闭类作为可以创建该新类型的 类时,这非常有用。例如:

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;
        }
    }
}

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

var subClassInstance = new Test.SubClass();

答案 3 :(得分:1)

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

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;
}

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