“Public” nested classes or not

隐身守侯 提交于 2019-11-30 01:55:05
Jon Skeet

I think it's fine. This is basically the builder pattern, and using nested classes works pretty well. It also lets the builder access private members of the outer class, which can be very useful. For instance, you can have a Build method on the builder which calls a private constructor on the outer class which takes an instance of the builder:

public class Outer
{
    private Outer(Builder builder)
    {
        // Copy stuff
    }

    public class Builder
    {
        public Outer Build()
        {
            return new Outer(this);
        }
    }
}

That ensures that the only way of building an instance of the outer class is via the builder.

I use a pattern very much like this in my C# port of Protocol Buffers.

You can use namespaces to relate things that are... related.

For example:

namespace Diner
{
    public class Sandwich
    {
        public Sandwich(Filling filling) { }
    }

    public class Filling { }
}

The advantage of this over using classes as if they were namespaces is that you can optionally use using on the calling side to abbreviate things:

using Diner;

...

var sandwich = new Sandwich(new Filling());

If you use the Sandwich class as if it were a namespace for Filling, you have to use the full name Sandwich.Filling to refer to Filling.

And how are you going to sleep at night knowing that?

You might want to check out what Microsoft has to say on the topic. Basically it's a question of style I'd say.

Another practical example that I have for a valid use of public nested classes is in MVC pattern when I use a viewmodel with an IEnumerable property. for example:

public class OrderViewModel
{
public int OrderId{ get; set; }
public IEnumerable<Product> Products{ get; set; }

public class Product {
public string ProductName{ get; set; }
public decimal ProductPrice{ get; set; }
}

}

I use it because I don't want Product class to be re-used outside because it is customized only for that specific viewmodel which contains it. But I can't make it private because the Products property is public.

I primarily use nested classes for fine-tuning access to the nested and/or the container class.

One thing to remember is that a nested class definition is basically a class member, and will have access to all the container's private variables.

You can also use this to control usage of a specific class.

Example:

public abstract class Outer
{
  protected class Inner
  {
  }
}

Now, in this case, the user (of your class) can only access the Inner class, if he implements Outer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!