6

I like using private nested classes, except that they always feel so cluttered. Normally I put them in their own #region, but I would prefer them to be separate from their parent class in terms of location, and I also don't really want them in separate files. What I decided to do was to make their parent class partial, and then to place the child class physically below the parent class in the file.

Unfortunately it seems that you can't have more than one partial class definition per file either.

(EDIT: it turns out you can have more than one partial part per file; it's just the forms designer that doesn't like it.)

What I would really like to do is something like (all in one file):

internal class Parent
{
}

private class Parent.Child1
{
}

private class Parent.Child2
{
}

but it seems like all I can do is either generate a new source file for every new child class, or arrange them like this:

internal class Parent
{
   private class Child1
   {
   }

   private class Child2
   {
   }
}

Is there any way to accomplish what I'm trying to do here?

Dave Cousineau
  • 12,154
  • 8
  • 64
  • 80
  • Multiple classes can be in the same file (in the same namespace), even when not nested - unlike Java there is no one [public] class restriction. If you want the Parent.Child naming relation then they must be nested, although partial classes could fake separation some .. – user2246674 Jun 06 '13 at 23:52

1 Answers1

9

The closest you can get to this type of encapsulation is using a partial parent class:

internal partial class Parent
{
    private Child1 c1Instance = new Child1();
    private Child2 c2Instance = new Child2();
}

internal partial class Parent
{
    private class Child1
    {
    }
}

internal partial class Parent
{
    private class Child2
    {
    }
}

You can split these up into multiple files, the end result will be the same - Child1 and Child2 will be private classes internal to Parent and inaccessible elsewhere.

Makes it a bit more confusing sometimes, but I think it's the closest thing to what you are trying to achieve.

Clarification

A C# source file can hold any number of namespaces, and each namespace can contain any number of structs and classes.

This is a valid (but not very functional) C# source file:

using System;

namespace FirstNS
{
    public class Class1
    {
    }

    public class Class2
    {
    }

    public partial class Parent1
    {
    }

    public partial class Parent1
    {
        private class Child1
        {
        }

        private class Child2
        {
        }
    }
}

namespace FirstNS.ChildNS
{
    public class Class3
    {
    }
}

Compiling that gives you the following classes:

FirstNS.Class1
FirstNS.Class2
FirstNS.Parent1
FirstNS.Parent1.Child1 (private)
FirstNS.Parent1.Child2 (private)
FirstNS.ChildNS.Class3

You could also split each of the class definitions above into multiple files, if you have a reason to do so.

Corey
  • 15,524
  • 2
  • 35
  • 68
  • This is what I was going to do, but you need to make a new file for every child class to do this. I'm looking for a way to not use many files but also not put them all together in one class definition. (I would like my one file to contain a bunch of distinctly defined classes, even though one is the parent of the others.) It seems like this is probably not possible. – Dave Cousineau Jun 06 '13 at 23:57
  • You don't need to use multiple files for this to work @Corey's solution looks good and will compile all in one .cs file – Daniel Flippance Jun 06 '13 at 23:59
  • @Sahuagin You can put everything in one file if you like, or split it among different files, whatever you prefer. You can define multiple namespaces in the same file, multiple classes, etc. When it makes sense to split them up, do. When it makes sense to keep them together, do that. – Corey Jun 07 '13 at 00:00
  • @Daniel Ok this does seem to work. It looks like it is only the forms designer that prevents you from having more than one partial part per file. Many thanks! – Dave Cousineau Jun 07 '13 at 00:05
  • +1. The other thing that often prevents people from doing is coming from Java (or maybe ActionScript) background where file name must match class name - there is no such restrictions in C# (good practice, but not required unlike in above languages). – Alexei Levenkov Jun 07 '13 at 00:50
  • 1
    @DaveCousineau: In response to your concerns about clutter: After you make all the separate files, open the .csproj file in a text editor (The Microsoft Power Commands extension provides support for doing this within Visual Studio). Replace `` with `parent.cs`. This puts your private nested classes underneath their parent in the hierarchy. Note that Visual studio uses this technique automatically with designer files. – Brian Nov 24 '17 at 15:44
  • Brian: nice, thanks. Just one thing: missing ">" after "DependentUpon". – TByte Oct 14 '20 at 10:46