What are nesting guys for?

Asked

Viewed 511 times

14

I know that C# supports nested types, that is, it is possible for me to declare one class within another. For example:

public class A
{
    // Propriedades e métodos da classe A

    public class B
    {
         // Propriedades e métodos da classe B
    }
}

I just never understood what it’s for. What this building can be used for and what the benefits?

2 answers

12


The most common is to use the internal type as private and so it works as an auxiliary type that can only be accessed internally. It’s a form of composition with a type that only concerns the type in question. That is, if the internal type will not be used elsewhere has no reason to expose it to other parts of the code.

You can thus hide an implementation detail by leaving more organized the part that is the detail. In most cases it is a matter of organization.

An important detail is that the internal type can access external type members, even private ones, without problems if necessary. Everything that has been created in a more external scope continues in the same scope. Nesting works in the same way as found in method algorithms.

I wouldn’t know how to quote an example where it would be appropriate to create a nested kind that is public.

Researching found some interesting examples in the OS, especially in Eric Lippert’s response where it shows a way where you can create your own hierarchy but prevent others from doing so:

public abstract class BankAccount {
    private BankAccount() {} // prevent third-party subclassing.
    private sealed class SavingsAccount : BankAccount { ... }
    private sealed class ChequingAccount : BankAccount { ... }
    public static BankAccount MakeSavingAccount() { ... }
    public static BankAccount MakeChequingAccount() { ... }
}

I put in the Github for future reference.

Note that he uses private and does not leave the default. In C# classes, by default sane internal, or are visible throughout Assembly. It would be almost the same as leaving public, after all you are creating a class within another but it would be accessible outside of it, so it would not have much advantage.

  • 4

    I don’t know how it is with C#, but if I remember well in Java there was another utility for nested types, even public - ensuring a compositional relationship between the "outside" type and the "inside" type. Because if to build an internal instance you always need an external reference (eg.: a = new A(); b = a.new B()) it is ensured that the composition exists and the A is never null (although the namespace of B is polluted by the internal limbs of A...). I don’t know if this makes sense in C# - or even if it’s a good idea in Java - but here’s the example.

11

Basically, scope limitation, but I’ll make a small change so that the utility is better understood:

public class A
{
    // Propriedades e métodos da classe A

    class B
    {
         // Propriedades e métodos da classe B
    }
}

Notice I removed the public of B. This is because class nesting is only truly useful when B is protected within the A.

And why is that?

Why your application might make use of the class only internally. A great example would be using the design standard Factory together with inheritance and immutable classes. Let’s use a concrete example:

public abstract class ContaBancaria
{
    private ContaBancaria() { }
    private sealed class ContaPoupanca : ContaBancaria { ... }
    private sealed class ContaCorrente : ContaBancaria { ... }
    public static ContaBancaria CriarContaCorrente() { ... }
    public static ContaBancaria CriarContaPoupanca() { ... }
}

In this case, I guarantee that what will be returned will either be a ContaCorrente or a ContaPoupanca, both of which are derived from ContaBancaria, unable to extend them (which could be a security problem) and without the ability to exploit constructors, if this class is part of an API, for example.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.