views:

165

answers:

6

I'm working with a 3rd party c# class that has lots of great methods and properties - but as time has gone by I need to extend that class with methods and properties of my own. If it was my code I would just use that class as my base class and add my own properties and method on top - but this class has an internal constructor. (In my opinion it was short sited to make the constructor internal in the first place - why limit the ability to subclass?)

The only thing I could think of was to create method / properties on my class that simply called into theirs - but it's acres of code and, well, it just doesn't "feel" right.

Is there any way to use this class a base class?

+3  A: 

Only if your class lives in the same assembly as the class you want to inherit from. An internal constructor limits the concrete implementations of the abstract class to the assembly defining the class. A class containing an internal constructor cannot be instantiated outside of the assembly.

The Matt
+2  A: 

Sounds like a perfect application for extension methods:

MSDN extension method docs

"Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type."

Bruce
You just 'new' it up the same way you do already - it magically gets new methods that you've added to it.
Bruce
Extension methods are only good in places where static methods can be used. Also, the namespace that contains the class with the extension methods must be included as well.Eg, you couldn't have properties that store state.
Nader Shirazie
Understood about the state - there are limitations. I don't understand your comment about static methods - sure, the extension method is static, but it has access to the object instance via the 'this' parameter.
Bruce
+1  A: 

If the class has an internal constructor, and there are no public constructors, then that suggests that the designers did not intend for it to be subclassed. In that case, you can use encapsulation, or you can use extension methods.

Eric Smith
+4  A: 

You ask: "Why limit the ability to subclass?"

Because designing for inheritance is tricky, particularly if you're designing for other developers to inherit from your class. As Josh Bloch says in Effective Java, you should design for inheritance or prohibit it. In my view, unless you have a good reason to design for inheritance, you shouldn't do so speculatively.

Does the class implement an interface which you could also implement (possibly by proxying most calls back to an instance of the original)? There's often no really elegant answer here - and the best solution will depend on the exact situation, including what you're trying to add to the class.

If you're not adding any more state - just convenience methods, effectively - then extension methods may work well for you. But they don't change what data an object is capable of storing, so if you need to add your own specialised data, that won't work.

Jon Skeet
A: 

I will not discuss whether you can build your own Facade around that 3rd party class. Previous authors are right, the library could be designed in the way that will not allow this. Suppose they have some coupled classes that have singletons that should be initialized in specific order or something like this - there may be a lot of design mistakes (or features) that 3rd party developers never care about, because they do not suppose that you will use their library in that way.

But OK, lets suppose that building a facade is not an impossible task, and you have in fact only one problem - there are too many methods you have to write wrappers around, and it is not good to do this manually.

I see 3 solutions to address exactly that problem

1) I suppose that new "dynamic" types of .NET 4.0 will allow you to workaround that problem without having to write "acres of code" You should incapsulate an instance of 3rd party class into your class as a privare member with dynamic keyword Your class should be derived from Dynamic or implement IDynamicObject interface. You will have to implement GetMember/SetMember functions that will forward all calls to the encapsulated instance of 3rd party class

Well, c# 4.0 is a future, Let's see on other solutions:

2) Do not write code manually if you have significant number of public methods (say more then 100). I would write a little console app that uses reflection and finds all public members and then automatically generates code to call encapsulated instance. For example

public type MethodName(params)
{
   this.anInstanceOf3rdPartyClass.MethodName(params);
}

3) You can do the same as 2, but with the help of existing reflection tools, for example RedGate .NET Reflector. It will help you to list all classes and methods signatures. Then, paste all this in Word and a simple VB macro will let you generate the same code as you could do in 2. Remark: As soon as you are not copying the code, but only copying method signatures, that are publicly available, I don't think you will violate the license agreement, but anyway it worth to re-check

Bogdan_Ch
+1  A: 

Resharper has a nice feature to create delegating members.

Here is a sample of what you can do with it. It takes a couple of seconds.

bh213