makerofthings7
makerofthings7

Reputation: 61483

Can a derived class in the CLR intercept / cloak a parent's class's methods, while still keeping intellisense?

Is it possible for the CLR to create Object X that inherits from Object Y where

An alternate implementation might use Generics where Object T<Y> exposes all the methods, events, and properties of contained object Y

Upvotes: 0

Views: 275

Answers (2)

Jamie Thomas
Jamie Thomas

Reputation: 1523

An alternative to runtime proxies that appears to match your requirements (running arbitrary code when methods on Y are called) but not your question (a subclassing strategy) would be AOP using compile-time solutions like PostSharp or Afterthought. This approach allows you to introduce code into existing methods in a compiled assembly and do pretty much whatever you want.

PostSharp works by allowing to to define attributes (aspects) that describe how you want to modify your classes. You would put these attributes on the methods, typed, assemblies, etc. and when PostSharp runs as a post-build step it will look for these attributes and perform transformations on the compiled assembly.

Afterthought works similarly using an attribute scheme to identify the amendments to apply to types in your assembly. However, Afterthought allows you to specify these attributes/amendments in one assembly and apply them to another assembly, such that you can actually modify a target assembly that does not have any attributes or references to Afterthought or potentially to the libraries you are introducing into it. I added this feature to Afterthought based on community feedback desiring the ability to perform elegant transformations without establishing a dependency on the AOP tool (Afterthought in this case) and potentially in cases where the original source code for an assembly is no longer available.

This is an example of using Afterthought to automatically output the execution time of every method call on an amended type:

public override void Amend(Method method)
{
    method.Context<Stopwatch>()

        .Before((T instance, string method, object[] parameters)
            => { var s = new Stopwatch(); s.Start(); return s; })

        .After((T instance, string method, Stopwatch stopwatch, object[] parameters)
            => Console.WriteLine(method + ": " + stopwatch.ElapsedMilliseconds);
}

In this case each method in an amended type is going to create a System.Diagnostics.Stopwatch instance at the beginning of each method and write out the name of the method and the execution time at the end of each method.

Upvotes: 0

mdm
mdm

Reputation: 12630

Yes. This is called proxying an object. Castle DynamicProxy is designed for doing exactly this. Krzysztof Koźmic has produced an excellent tutorial about it.

It works by creating an object (X in your scenario) at runtime which inherits from the object you want to proxy (object Y). You provided an object which implements IInterceptor which gets called when certain methods are invoked - you specify these in a proxy generation options class.

The only caveat is that the methods you wish to intercept must be virtual, but you can probably get around this by wrapping the object to proxy in another which does provide virtual methods (although I'd guess you probably want to proxy the object because doing this is a real pain).

Upvotes: 1

Related Questions