Nested classes are not necessary here, for anyone having trouble understanding, the following is a nested class approach:
public class Car
{
public static Car Instance { get; private set; }
static Car() { Car.Instance = new Car(); }
private Car() { }
public static class Door
{
public static void Close()
{
/* do something with Car.Instance */
}
}
}
The use of static classes yields the following syntax:
Car.Door.Close();
C# allows you to nest class definitions it does not have a formal concept of 'inner types' or 'inner classes' as other languages do.
This is an excellent example of poor component modeling/design.
Consider the following, which is a more acceptable and more elegant solution:
public interface ICar
{
IDoor Door { get; set; }
}
public class Car : ICar
{
public IDoor Door { get; set; }
}
public interface IDoor
{
void Open();
void Close();
}
public class Door : IDoor
{
public override void Open() { /* do something */ }
public override void Close() { /* do something */ }
}
With the above could use C#'s initializer syntax:
var car = new Car
{
Door = new Door()
};
car.Door.Open();
If your gripe is with constantly needing to type "new XYZ" you can also bake initialization into the constructor. Done properly with a 'poor man' DI pattern it should look like this:
public class Car : ICar
{
public IDoor Door { get; set; }
public Car()
: this(new Door())
{
}
public Car(IDoor door)
{
this.Door = door;
}
}
This avoids the need to perform initialization as part of creation, and allows you to inject new/different Door types into the stack.
var common = new Car();
var lambo = new Car(new LamboDoor());
In either case, calling code looks the same:
common.Door.Open();
lambo.Door.Open();
Lastly, you could consider a Composition or DI framework rather than bake new() operators into your implementation code. In any case, the most appropriate approach is to use properties and construct a legitimate object model which expresses your intent. Nested types do not yield the syntax you're looking for unless static members are used and taking that approach is very rarely a good idea, I've only seen it for simplistic singleton implementations, certainly never for API/Framework/Model definition.