Tuesday, March 24, 2009
Inner Classes for Organization
C#.NET allows you to define inner classes. An inner class is defined within the scope of another class. There are all kinds of cool things you can do with them. But, one of the most basic uses is to simply an inner class as an organizational container.
For example, lets say we have a class that implements the
If our class is going to implement
The traditional approach would be to write a class something like the one shown below.
But, there is no reason why we couldn't (and shouldn't) encaspulate those property constants into their own container via an inner class.
In the first example, the constant can be accessed with syntax like
In the second example, note that the inner class is defined with the
Imagine if the inner class in the second example was not static.
Now, if we derive a new class from
That little trick with the inner class derived from the base inner class is pretty cool because the new
For example, lets say we have a class that implements the
System.ComponentModel.INotifyPropertyChanged interface. That interface has a single member -- the PropertyChanged event of type PropertyChangeEventHandler. The PropertyChangedEventHandler, in turn, uses PropetyChangeEventArgs as the event arguments, and the PropertyChangedEventArgs don't tell you much except the name of the property that changed. If our class is going to implement
INotifyPropertyChanged, it also follows that we probably need to define some constants (or static readonly fields) for the various properties that may raise the PropertyChanged event.The traditional approach would be to write a class something like the one shown below.
public class Class1a : INotifyPropertyChanged
{
public static readonly string MyFirstPropertyName = "MyFirstProperty";
public static readonly string MySecondPropertyName = "MySecondProperty";
public event PropertyChangedEventHandler PropertyChanged;
...
}
But, there is no reason why we couldn't (and shouldn't) encaspulate those property constants into their own container via an inner class.
public class Class1b : INotifyPropertyChanged
{
public static class PropertyNames
{
public static readonly string MyFirstProperty = "MyFirstProperty";
public static readonly string MySecondProperty = "MySecondProperty";
}
public event PropertyChangedEventHandler PropertyChanged;
...
}
In the first example, the constant can be accessed with syntax like
Class1a.MyFirstPropertyName. In the second example, the syntax is a bit more verbose but perhaps easier to use, especially with the context-sensitive drop downs of Visual Studio: Class1b.PropertyNames.MyFirstProperty.In the second example, note that the inner class is defined with the
static keyword. That is not required, as it basically just serves as a way of making the compiler enforce that the class contains nothing but static members. That is what we want in this case. But, the downfall of a static class -- whether it is an inner class or not -- is that it cannot be derived from any class other than System.Object. That prohibits us from doing what I am going to show you next.Imagine if the inner class in the second example was not static.
public class Class1c : INotifyPropertyChanged
{
public class PropertyNames
{
public static readonly string MyFirstProperty = "MyFirstProperty";
public static readonly string MySecondProperty = "MySecondProperty";
}
public event PropertyChangedEventHandler PropertyChanged;
...
}
Now, if we derive a new class from
Class1c, we can also define a new inner class that is derived from the inner class of the base class.
public class MyClass2 : MyClass1c
{
public new class PropertyNames : Class1c.PropertyNames
{
public static readonly string MyThirdProperty = "MyThirdProperty"
}
...
}
That little trick with the inner class derived from the base inner class is pretty cool because the new
PropertyNames class inherits the constants, fields, properties and methods of the base inner class. Therefore, we can not only access the new constants by MyClass2.PropertyNames.MyThirdProperty, but also continue to access the old constants with MyClass1c.PropertyNames.MyFirstProperty or MyClass2.ProprtyNames.MyFirstproperty.Subscribe to Posts [Atom]