Inheriting from MarshalByRefObject

Developers often wonder why they are forced to derive from MarshalByRefObject or EnterpriseServices.ServicedComponent. It would be so much more convenient if they could add a CustomAttribute to their class or use a marker interface to declare that they want to be marshaled by reference or they want serviced behavior.

The reason has to do with performance. The CLR has a large number of optimizations which it can apply to objects that are guaranteed to be local. If the object is possibly remote, then these optimizations are invalidated. Examples include method inlining by the JIT, direct field access, fast instantiation in the local heap, direct method invocation for non-virtuals and more efficient type tests like cast operations.

When the benefit of these optimizations is considered, it completely outweighs the programming model impact to the inheritance hierarchy. This decision is key to achieving our long term goal of performance parity with native code.

Comments (8)

  1. Julie LErman says:

    Chris- I just want to stop working and wait with baited breath for every new gem that you post. Thank you thank you. You have no idea…

  2. You could give us the ability to access non-MarshalByRefObject objects by reference through interfaces, though. That would be mondo useful.

  3. Ingo Rammer says:

    Dejan: That’s not easily possible because the complete lifetime tracking is done by the MarshalByRefObject as well. I.e. the ILease-object is bound to a MarshalByRefObject.

    It should however easily be possible (even now with .NET 1.0 or 1.1) to write a helper class to create corresponding MBR aggregates/wrappers for any class by using reflection and Reflection.Emit on the server side. On the client side, the interface should be enough.

  4. Ingo, that’s what I’m doing right now, but proxy objects are giving me headaches in situations where the object’s identity is important.

Skip to main content