Working on a custom web-control I have been struggling a little with the visibility of class members. What I wanted to do is define functionality in a base class, keep that hidden and publish parts of it in descendent classes. Take this example :
public abstract class Class1
{
public Class1()
{
}
protected virtual string m1()
{
return "One";
}
protected virtual string m2()
{
return "Two";
}
}
The class is declared as abstract to prevent instances of it being created. The functionality is in the two methods, they are both protected to hide them. Two new classes are based on this class, one will only expose the method m1, the other will only expose m2. The easiest approach would be to create new methods which use the protected methods of the base class. But I want to keep the existing method names and signatures. The first approach exactly describes my intentions :
public class Cd1 : Class1
{
public override string m1()
{
return base.m1();
}
}
But this will not compile. You cannot change the visibility of a member. The workaround is to use the new modifier to hide the inherited method.
public class Cd1 : Class1
{
public virtual new string m1()
{
return base.m1();
}
}
public class Cd2 : Class1
{
public virtual new string m2()
{
return base.m2();
}
}
The good thing is that I can still use the implementation of the base class in the new method. By declaring the method as virtual I can override the method again in descending classes
public class Cd11 : Cd1
{
public override string m1()
{
return base.m1() + " derived";
}
}
Working this way was inspired by Delphi (again, breaking up is hard to do). In Delphi you can change the visibility of members. All you need to do is re-declare a protected member as a published property. Published is Delphi speak for a reflectable public member. The VCL, Delphi's class library, uses this technique a lot. It contains for most controls a custom base class. All functionality of the control is defined in there. Building the control boils down to publishing those methods you need in the control.
The FCL does not have that kind of base-classes. I was creating a link-button and wanted to hide the commandname property. In Delphi I would have published selected properties from the custom linkbutton base class, but the FCL LinkButton inherits directly from the WebControl class. If I used that as a base class would mean I would lose all the desired inherited Linkbutton functionality as well. As a second approach I tried to override the CommandName property, alas it is not virtual. So I had to make up a story to turn this "bug" in a feature.
I prefer the C# syntax to change the visibility of a member. It does take a little more typing than the Delphi way (usually it is the other way round) but is clearer and more flexible. But I would love to have something like the custom base classes in the framework.
Blog on.
Peter