Hierarchical structuring of Functions inside a Class (C#) - c#

is it possible to structure functions inside a class, to make some functions only accessable through a prewritten identifier?
I'll try to make my question a litte more clear with a (poor) example ;-) My class car got the functions drive, openDoor, closeDoor, startEngine, etc. But, to keep it clear, i would like to acces these functions like this:
car.drive()
car.door.open()
car.door.close()
car.engine.start()
I tried with structs and nested classes, but i don't think those were the right ways, because i don't like to have to create an object for every "identifier" i use.
Are there any "clean" ways to do this?
Thanks!
Edit:
I'm not sure if it matters but heres some additional information:
the "Car"-Class is Singelton
apart from the functions neither the engine nor the doors or any other part of my car do have any other properties (Yay. Really poor example!)

Nested classes would be the correct approach.
Consider that all Door objects would have Open and Close methods, and a Car object would have several instances of the Door object (2, maybe 4, or even more).
Likewise, each Car object would have an instance of the Engine object, which can be Started, Stopped, and have the oil changed (ChangeOil).
Then, each of these classes would be extensible beyond the Car class. If you wanted to change some of the code inside of your Door class, all of your Car objects that have Doors would automatically inherit those changes. If you wanted to swap out the engine of a car with a more powerful one, you could do that easily by passing in a new instance of the Engine object to your Car object.
You could use structs the same way that you would use classes, but generally you should choose to use a class rather than a struct. Structs should be reserved for types that should have value type semantics, i.e., are small, immutable, etc. For more information on the difference and how to make an informed decision, see this question.
And just in case I failed to convince you that nested classes are the correct approach, I'll conclude by noting that they're also the only way of achieving what you want. That is, beyond hacky solutions like appending a pseudo-namespace to the beginning of each function name (i.e., Car.DoorOpen), which is ugly and doesn't really gain you anything at all.

No - you would need to have a nested class door with its own methods. You could add your descriptor to the method name. So you would have
car.DoorOpen();
car.DoorClose();
I'd go for classes, since you may have properties that would apply more to the class door than to car. And add properties of the class door to car.
car.Door.Open();

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.

Just my 2 sense.
I like #Code Gray idea of nested classes. But to achieve the correct order of calling the methods, I think you need to nest car under Driver. The Driver would do something like this.
public class Driver
{
public void Drive(Car car)
{
car.drive();
car.door.open();
car.door.close();
car.engine.start();
}
}

Related

How can I make a polymorphic method with different signatures

Consider I have some abstract Vehicle class and car, truck, motorcycle abstract classes which derive from Vehicle. Also imagine that I have to be able to create a fueled based car or electric based car and so on for truck and motorcycle as well. (concrete classes)
Two questions:
1.Consider that I want to fill up energy in a vehicle without knowing what it is, in a polymorphic way. For example if the vehicle is fuel based I want to fill it with fuel and the method should be with 3 parameters:
void FillUpEnergy(EfuelType i_fuelType,int amounOfEnergy, int maxAmountOfEnergy)
but for electricy based vehicle I need almost the same function signture but this time without fuel type of course, for example (2 parameters):
void FillUpEnergy(int amounOfEnergy, int maxAmountOfEnergy)
Can I do a polymorhic FillUpEnergy method with the above constraints? (different method's signatures)
2.In my implementation all the concrete classes hold a reference for Engine(another abstract class) which represent a FuelEngine or ElectricEngine (other concrete classes I have which derive from Engine). For example I have a concrete class named ElectricCar which holds a reference for ElectricEngine.
Is this architecture good enough or are there better ways to implement a garage system?
(In terms of Object oriented design etc..)
You cannot make a polymorphic "push-style" method with different signatures, but you can make a polymorphic "pull-style" method using the well-publicized Visitor Pattern.
The idea is to invert the sequence of interaction, and let the car object decide what to do: Instead of calling FillUpEnergy and giving the car what you think it needs, call FillUpEnergy and let the car take what it knows it needs, like this:
interface IEnergyProvider {
void TakeFuel(EfuelType i_fuelType, int amounOfEnergy);
void TakeElectricity(int amounOfEnergy);
}
interface ICar {
void FillUpEnergy(IEnergyProvider provider);
}
Now the signature of your polymorphic method is fixed, but the dispatch of the method takes two legs instead of one:
You call myCar.FillUpEnergy(myProvider)
The car calls myProvider.TakeFuel or myProvider.TakeElectricity
Regarding question 1)
You could make electric/gasoline part of the fueltype and handle this in your domain logic.
C# does not offer polymorphism with different signatures.
2) is called Composition
What distinguishes the ElectricCar from the FueledCar? Nothing but the engine (conceptually):
interface IEngine
{
void FillUpFuel(int amountOfFuel, int maxAmountOfFuel);
}
class ElectricEngine : IEngine
{
public void FillUpFuel(int amountOfFuel, int maxAmountOfFuel) { ... }
}
abstract class Vehicle
{
public abstract IEngine Engine { get; }
}
class Car : Vehicle
{
public IEngine _engine;
public override IEngine Engine { get { return _engine; } }
public Car(IEngine engine)
{
_engine = engine;
}
}
...
var electricCar = new Car(new ElectricEngine());
electricCar.Engine.FillUpFuel(40, 70);
Typical composition vs inheritance example. Naming is a bit odd with ElectricEngine filling up fuel... but that's not the point.
About 1)
The point of having FillUpEnergy polymorphic (subtype polymorphism) is to be able to call this method when the only thing you know is that the object is a Vehicle.
If you need to know the exact type in order to choose the correct set of argument, then their is no need for this function to be polymorphic.
About 2)
Nothing's shocking
You can't do that, because it would be exactly a violation of encapsulation.
I don't understand your question regarding engines, but I can surely say that there could be a lot of better ways to implement "garage system" just because there are so many different "garage systems". Which in fact means that you should not try to model your system (in terms of OOP or any other terms) until you get a good grasp of your requirements.

Only allow setting a property from a specific class / instance

imagine I have two classes A and B where B has the properties BProperty1 and BProperty2.
The property BProperty1 shall only be settable by class A (no matter which instance)
The property BProperty2 shall only be settable by a concrete instance of class A (the reference to this instance could e.g. be stored on BProperty1).
Is it possible to realize something like that, is there maybe a pattern for it? Please note that A and B are independent, none of them derives from the other one! I'm using C# and WPF. Thanks for any hint!
EDIT
An example:
Imagine a class Car and a class CarDoor. Whenever a CarDoor is added to a Car, the CarDoors property AssociatedCar is set to the Car it's assigned to, because this reference is needed later. But how to make sure the AssociatedCar property is not set by the user, but by the Car class when AddCarDoor(door) is called?
class Car
{
private List<CarDoor> _carDoors = new List<CarDoor>();
public Car()
{
}
public void AddCarDoor(CarDoor door)
{
// Add the door to the car
_carDoors.Add(door);
// Save a reference to the car assigned to the door
door.AssociatedCar = this;
}
}
class CarDoor
{
public Car AssociatedCar;
public CarDoor()
{
}
}
You could lock the setter, then make the object required to unlock it private to class A.
Edit: After seeing your edit, I would suggest that you make a car door a member of class car, seeing as how a car is composed of some x doors. Or perhaps a collection of car doors. Make that member variable private. Then nothing outside of the car class will be able to edit that property of the car door.
Edit2: Also, having a two way association between car and car door (i.e. car door has an associated car, and car has associated car doors) is a bit redundant. I do not see why you would need it - simply set a public get property for the car door, so that you can use that data outside of the car class.
Example...
Class Car
{
private List<CarDoor> carDoors;
Car()
{
this.carDoors = new List<CarDoor>();
}
public List<CarDoor> getCarDoors
{
return this.carDoors;
}
}
Here's one design that shifts responsibilities slightly to create the two-way dependency:
class CarFactory
{
public Car BuildCar()
{
return new Car(BuildDoor);
}
public CarDoor BuildDoor(Car car)
{
return new CarDoor(car);
}
}
class Car
{
private List<CarDoor> _carDoors = new List<CarDoor>();
public Car(Func<Car, CarDoor> buildDoor)
{
for (int i=0; i<4; i++)
_carDoors.Add(buildDoor(this));
}
}
class CarDoor
{
private Car _associatedCar;
public CarDoor(Car associatedCar)
{
_associatedCar = associatedCar;
}
}
Note, however, that this sort of two-way dependency is a sign of other problems. It could be that CarDoor is doing things that it shouldn't be responsible for doing. Perhaps Car should be doing these things or perhaps you've included responsibilities that really belong in another class entirely, like Mechanic.
You can put the two together in a separate project/assembly/dll and use the internal keyword on the property set. That way any class inside the assembly can change the property, but since you're in control of the entire thing you can make sure only Car does so.
If it is a property, you may want to use System.Diagnostics.StackTrace class) inside the property setter. You just need to check the assembly and the class which called the setter, and throw an exception if it is a class other than the class A.
Notes:
Be aware of performance issues.
I'm pretty sure that somebody will say that if you need to do this sort of things, it means that there is a flaw in your object-oriented approach. At least, I used this once, and I completely agree that my approach was wrong.

Any real example of using interface related to multiple inheritance

I m trying to understand Interfaces so that I can implement them in my programs but I m not able to imagine how should i use them.
Also give me some eg of using them with multiple inheritance in C#
A good example for an interface is a repository pattern. Your interface will define methods like Get, GetAll, Update, Delete, etc. No implementation, just function signatures.
Then, you can write a 'concrete' implementation of that class to work with, say, MySQL. Your UI should only refer to the interface, though.
Later, if you decide to change to Microsoft SQL, you write another concrete implementation, but your UI code doesn't have to change (much).
Multiple inheritance doesn't exist in C#, in the sense that you can only inherit from one 'concrete' class; though you can inherit (or 'implement') as many interfaces as you want.
I am writing a video game. In this video game I apply different forces to objects in the game. Thrust forces, impact forces, gravitational forces. While they are calculated differently, they all have the same basic elements. I need to call an update function that will evaluate the force and add the force to the object it's attached to.
So, what I've done is create an IForce interface that has an update function for its signature. All of my forces implement this interface:
public interface IForce
{
void Update(Particle particle, GameTime gameTime);
}
Here is a sample implementation.
public class Spring : IForce
{
private Particle ThisParticle;
private Particle ThatParticle;
private float K;
public Spring(Particle thisParticle, Particle thatParticle, float k)
{
ThisParticle = thisParticle;
ThatParticle = thatParticle;
}
public void Update(Particle particle, GameTime gameTime)
{
float X = Vector3.Length(ThisParticle - ThatParticle);
ThisParticle.Forces.Add(K * X);
}
}
The update function has a simplified spring force update to make it easier to understand.
This helps in a few ways.
I can completely change the way a force is calculated without effecting other parts of my code. I do this all the time. Along the same lines, it is rediculously easy for me to add new forces. As long as it implements the IForce interface I know it will mesh well with my existing code.
Another way it helps is with handling a large number of forces. I have a force registry that has a List of IForce. Since all forces implement that interface and have an Update function it's very easy to update all the forces in my game. When I create the force I add it to the list. Then, I loop through the list and call each elements update function without worrying about what type of force it is and all my forces update.
I use interfaces every day in a lot of different situations. They are fantastic!
Note :Interface is used to restrict and access the methods or events etc from differents classes at any cost, It means we can defined many more methods inside any class but when we are calling methods through Interface means we want only other than restricted methods. In the program below User1 can use Read & Write both but User2 can Write and Execute. See this Program below.........
namespace ExplConsole
{
class Program
{
static void Main ()
{
System.Console.WriteLine("Permission for User1");
User1 usr1 = new Test(); // Create instance.
usr1.Read(); // Call method on interface.
usr1.Write();
System.Console.WriteLine("Permission for User2");
User2 usr2 = new Test();
usr2.Write();
usr2.Execute();
System.Console.ReadKey();
}
}
interface User1
{
void Read();
void Write();
}
interface User2
{
void Write();
void Execute();
}
class Test : NewTest,User1, User2
{
public void Read()
{
Console.WriteLine("Read");
}
public void Write()
{
Console.WriteLine("Write");
}
}
class NewTest
{
public void Execute()
{
Console.WriteLine("Execute");
}
}
}
Output:
Permission for User1
Read
Write
Permission for User2
Write
Execute
Interfaces simply define a contract of the public elements (e.g. properties, methods, events) for your object, not behavior.
interface IDog
{
void WagTail(); //notice no implementation
ISound Speak(); //notice no implementation
}
class Spaniel : IDog
{
public void WagTail()
{
Console.WriteLine("Shook my long, hairy tail");
}
public ISound Speak()
{
return new BarkSound("yip");
}
}
class Terrier : IDog
{
public void WagTail()
{
Console.WriteLine("Shook my short tail");
}
public ISound Speak()
{
return new BarkSound("woof");
}
}
UPDATE
In "real examples" I use interfaces with:
- Unit Testing
- GENERICS (e.g. Repository, Gateway, Settings)
interface Repository<T>{
T Find(Predicate<T>);
List<T> ListAll();
}
interface Gateway<T>{
T GetFrom(IQuery query);
void AddToDatabase(IEntity entityItem);
}
interface Settings<T>{
string Name { get; set; }
T Value { get; set; }
T Default { get; }
}
Here is one (in Java, but this is not important since they're similiar):
In my project I've created simple interface:
public interface Identifiable<T> {
public T getId();
}
Which is simple replacement to some sorts of annotations. The next step: I've made all entity classes implement this interface.
The third step is to write some syntax-sugar-like methods:
public <T> List<T> ids(List<? extends Identifiable<T> entities) { ... }
This was just an example.
The more complex example is something like validation rules: you have some validation engine (probably written by you) and a simple interface for rule:
public interface ValidationRule {
public boolean isValid(...);
}
So, this engine requires the rules to be implemented by you. And of course there will be multiple inheritance since you'll certainly wish more then a single rule.
Multiple inheritance is about having a class be usable in multiple situations: [pseudo code]
interface Shape {
// shape methods like draw, move, getboundingrect, whatever.
}
interface Serializable {
// methods like read and write
}
class Circle : public Shape, public Serializable {
// TODO: implement Shape methods
// TODO: implement Serializable methods
}
// somewhere later
{
Circle circle;
// ...
deserializer.deserialize(circle);
// ...
graphicsurface.draw(circle);
// ...
serializer.serialize(circle);
}
The idea is that your Circle class implements two different interfaces that are used in very different situations.
Sometimes being too abstract just gets in the way and referring to implementation details actually clarifies things. Therefore, I'll provide the close to the metal explanation of interfaces that made me finally grok them.
An interface is just a way of declaring that a class implements some virtual functions and how these virtual functions should be laid out in the class's vtable. When you declare an interface, you're essentially giving a high-level description of a virtual function table to the compiler. When you implement an interface, you're telling the compiler that you want to include the vtable referred to by that interface in your class.
The purpose of interfaces is that you can implicitly cast a class that implements interface I to an instance of interface I:
interface I {
void doStuff();
}
class Foo : I {
void doStuff() {}
void useAnI(I i) {}
}
var foo = new Foo();
I i = foo; // i is now a reference to the vtable pointer for I in foo.
foo.useAnI(i); // Works. You've passed useAnI a Foo, which can be used as an I.
The simple answer, in my opinion, and being somewhat new to interfaces myself is that implementing an interface in a class essentially means: "This class MUST define the functions (and parameters) in the interface".
From that, follows that whenever a certain class implements the interface, you can be sure you are able to call those functions.
If multiple classes which are otherwise different implement the same interface, you can 'cast' them all to the interface and call all the interface functions on them, which might have different effects, since each class could have a different implementation of the functions.
For example, I've been creating a program which allows a user to generate 4 different kinds of maps. For that, I've created 4 different kind of generator classes. They all implement the 'IGenerator' interface though:
public interface IGenerator {
public void generateNow(int period);
}
Which tells them to define at least a "public generateNow(int period)" function.
Whatever generator I originally had, after I cast it to a "IGenerator" I can call "generateNow(4)" on it. I won't have to be sure what type of generator I returned, which essentially means, no more "variable instanceof Class1", "variable instanceof Class2" etc. in a gigantic if statement anymore.
Take a look at something you are familiar with - ie a List collection in C#. Lists define the IList interface, and generic lists define the IList interface. IList exposes functions such as Add, Remove, and the List implements these functions. There are also BindingLists which implement IList in a slightly different way.
I would also recommend Head First Design Patterns. The code examples are in Java but are easily translated into C#, plus they will introduce you to the real power of interfaces and design patterns.

Force singleton pattern in subclasses

I would like to force subclasses to implement the singleton pattern.
I originally thought of having an abstract static property in the parent class, but upon closer though, that didn't make sense (abstract requires and instance).
Next, I thought of having an interface with a static property, but that also doesn't make sense (interfaces also require an instance).
Is this something which is possible, or should I give up this train of thought and implement an abstract factory?
Please reconsider. You do NOT want to use singletons here. You are making some functionality available to users who derive from your class. That's fine. But you're also dictating one specific way in which it must always be used, and for absolutely no reason. That is not good.
It may make sense to only instantiate one object of this class the majority of the time, but in that case, simply just instantiate the object once. It's not like you're very likely to accidentally instantiate a dozen objects without noticing.
Moreover, how can you tell that having two instances will NEVER be useful? I can think of several cases even now.
Unit testing: You might want each test to instantiate this object, and tear it down again afterwards. And since most people have more than one unit test, you'll need to instantiate it more than once.
Or you might at some point decide to have multiple identical/similar levels in your game, which means creating multiple instances.
A singleton gives you two things:
A guarantee that no more than one instance of the object will ever be instantiated, and
Global access to that instance
If you don't need both these things, there are better alternatives.
You certainly don't need global access. (globals are bad, and usually a symptom of bad design, especially in mutable data such as your game state)
But you don't need a guarantee that no more than one instances will ever be instantiated either.
Is it the end of the world if I instantiate the object twice? Will the application crash? If so, you need that guarantee.
But in your case, nothing bad will happen. The person instantiating the object simply uses more memory than necessary. But he might have a reason.
Simply put in the class documentation that this is a very big and expensive class, and you shouldn't instantiate it more often than necessary. Problem solved. You don't remove flexibility that might turn out to be useful later on, you don't grant global access to data for no reason. Because you can control who can see the object, you don't need to drown it in locks that will become a bottleneck in multithreaded applications. You don't have hidden dependencies scattered throughout your code, making it harder to test and harder to reuse.
Try using an IOC container. Most good IOC containers enable the use of the singleton pattern without having to implement it yourself (ie: spring framework) - I like this better than forcing a static GetInstance() method.
Besides, it's not really possible in java, it would work in C++ with templates though.
Why? If someone wants to use multiple instances of a subclass of your class they might have a perfectly valid reason to.
If you want to do something that only should be done once for each class that subclasses your class (why, I have no idea, but you might have a reason to), use a Dictionary in the base class.
I would define a sealed class that gets its functionality from delegates passed to the constructor, something like this:
public sealed class Shape {
private readonly Func<int> areaFunction;
public Shape(Func<int> areaFunction) { this.areaFunction = areaFunction; }
public int Area { get { return areaFunction(); } }
}
This example does not make a lot of sense, it just illustrates a pattern.
Such a pattern cannot be used everywhere, but sometimes it helps.
Additionally, it can be extended to expose a finite number of static fields:
public sealed class Shape {
private readonly Func<int> areaFunction;
private Shape(Func<int> areaFunction) { this.areaFunction = areaFunction; }
public int Area { get { return areaFunction(); } }
public static readonly Shape Rectangle = new Shape(() => 2 * 3);
public static readonly Shape Circle = new Shape(() => Math.Pi * 3 * 3);
}
I think you will be better off with a factory pattern here to be honest. Or use an IoC tool like Brian Dilley recommends. In the c# world there are loads, here are the most popular : Castle/windsor, StructureMap, Unity, Ninject.
That aside, I thought it would be fun to have a go at actually solving your problem! Have a look at this:
//abstract, no one can create me
public abstract class Room
{
protected static List<Room> createdRooms = new List<Room>();
private static List<Type> createdTypes = new List<Type>();
//bass class ctor will throw an exception if the type is already created
protected Room(Type RoomCreated)
{
//confirm this type has not been created already
if (createdTypes.Exists(x => x == RoomCreated))
throw new Exception("Can't create another type of " + RoomCreated.Name);
createdTypes.Add(RoomCreated);
}
//returns a room if a room of its type is already created
protected static T GetAlreadyCreatedRoom<T>() where T : Room
{
return createdRooms.Find(x => x.GetType() == typeof (T)) as T;
}
}
public class WickedRoom : Room
{
//private ctor, no-one can create me, but me!
private WickedRoom()
: base(typeof(WickedRoom)) //forced to call down to the abstract ctor
{
}
public static WickedRoom GetWickedRoom()
{
WickedRoom result = GetAlreadyCreatedRoom<WickedRoom>();
if (result == null)
{
//create a room, and store
result = new WickedRoom();
createdRooms.Add(result);
}
return result;
}
}
public class NaughtyRoom :Room
{
//allows direct creation but forced to call down anyway
public NaughtyRoom() : base(typeof(NaughtyRoom))
{
}
}
internal class Program
{
private static void Main(string[] args)
{
//Can't do this as wont compile
//WickedRoom room = new WickedRoom();
//have to use the factory method:
WickedRoom room1 = WickedRoom.GetWickedRoom();
WickedRoom room2 = WickedRoom.GetWickedRoom();
//actually the same room
Debug.Assert(room1 == room2);
NaughtyRoom room3 = new NaughtyRoom(); //Allowed, just this once!
NaughtyRoom room4 = new NaughtyRoom(); //exception, can't create another
}
}
WickedRoom is a class that properly implements the system. Any client code will get hold of the singleton WickedRoom class. NaughtyRoom does not implement the system properly, but even this class can't be instantiated twice. A 2nd instantiation results in an exception.
Although this will not enforce the user to have a singleton subclass, you can enforce the user to create only one instance of the class (or its sub-classes) as below. This will throw error if a second instance of any subclass is created.
public abstract class SuperClass {
private static SuperClass superClassInst = null;
public SuperClass () {
if(superClassInst == null) {
superClassInst = this;
}
else {
throw new Error("You can only create one instance of this SuperClass or its sub-classes");
}
}
public final static SuperClass getInstance() {
return superClassInst;
}
public abstract int Method1();
public abstract void Method2();
}

Private inner classes in C# - why aren't they used more often?

I am relatively new to C# and each time I begin to work on a C# project (I only worked on nearly mature projects in C#) I wonder why there are no inner classes?
Maybe I don't understand their goal. To me, inner classes -- at least private inner classes -- look a lot like "inner procedures" in Pascal / Modula-2 / Ada : they allow to break down a main class in smaller parts in order to ease the understanding.
Example : here is what is see most of the time :
public class ClassA
{
public MethodA()
{
<some code>
myObjectClassB.DoSomething(); // ClassB is only used by ClassA
<some code>
}
}
public class ClassB
{
public DoSomething()
{
}
}
Since ClassB will be used (at least for a while) only by ClassA, my guess is that this code would be better expressed as follow :
public class ClassA
{
public MethodA()
{
<some code>
myObjectClassB.DoSomething(); // Class B is only usable by ClassA
<some code>
}
private class ClassB
{
public DoSomething()
{
}
}
}
I would be glad to hear from you on this subject - Am I right?
Nested classes (probably best to avoid the word "inner" as nested classes in C# are somewhat different to inner classes in Java) can indeed be very useful.
One pattern which hasn't been mentioned is the "better enum" pattern - which can be even more flexible than the one in Java:
public abstract class MyCleverEnum
{
public static readonly MyCleverEnum First = new FirstCleverEnum();
public static readonly MyCleverEnum Second = new SecondCleverEnum();
// Can only be called by this type *and nested types*
private MyCleverEnum()
{
}
public abstract void SomeMethod();
public abstract void AnotherMethod();
private class FirstCleverEnum : MyCleverEnum
{
public override void SomeMethod()
{
// First-specific behaviour here
}
public override void AnotherMethod()
{
// First-specific behaviour here
}
}
private class SecondCleverEnum : MyCleverEnum
{
public override void SomeMethod()
{
// Second-specific behaviour here
}
public override void AnotherMethod()
{
// Second-specific behaviour here
}
}
}
We could do with some language support to do some of this automatically - and there are lots of options I haven't shown here, like not actually using a nested class for all of the values, or using the same nested class for multiple values, but giving them different constructor parameters. But basically, the fact that the nested class can call the private constructor gives a lot of power.
The Framework Design Guidelines has the best rules for using nested classes that I have found to date.
Here's a brief summary list:
Do use nested types when the relationship between type and nested type is such the member-accessibility semantics are desired.
Do NOT use public nested types as a logical group construct
Avoid using publicly exposed nested types.
Do NOT use nested types if the type is likely to be referenced outside of the containing type.
Do NOT use nested types if they need to be instantiated by client code.
Do NOT define a nested type as a member of an interface.
You should limit the responsibilities of each class so that each one stays simple, testable and reusable. Private inner classes go against that. They contribute to the complexity of the outer class, they are not testable and they are not reusable.
For me personally I only create private inner classes if I need to create in-process collections of an object that may require methods on them.
Otherwise, it could cause confusion for other developers working on the project to actually find these classes, as they are not very clear as to where they are.

Categories

Resources