ServicesResourcesConferencesOur TeamWeblogsAboutContact
   
MarshalByRefObject

Jason wonders about some Great mysteries of the CLI

Also - why is [Serializable] an attribute while MarshalByRefObject is a base class? The arguments I've heard are pretty weak. As Mike Woodring points out, deriving from MBRO means inlining of methods has to be disabled.  And who derives from MBRO?  EVERY SINGLE class in the Winforms hierarchy.

As someone who spent a good six months of his life inside the Remoting stack, I certainly do have an opinion on this. At the beginning, I definitely thought the same way. Why the heck didn't they implement yet another attribute for designating an object as a remoteable one? This way, I could easily later flag classes deeper down in my class hierarchy to be remoteable. And that's the very answer as well. This just isn't possible.

Let's say you have the following method:

public void foo(bar x)
{
   x.baz()
}
And you have an inheritance hierarchy of [System.Object]<-[bar]. In this case, the JIT could inline the call to baz().
 
If you'd use attributes to designate MarshalByRef (or "proxyable") semantics, you could then extend the hierarchy: [System.Object]<-[bar]<-[foobar] and flag foobar with this attribute. Bad thing. The JIT now must not inline the call to baz().
 
The only possible way to solve this is to have [System.MarshalByRefObject]<-[bar] because this way, the JIT knows right from the start not to inline the call to baz() and everything will be fine.
 
Still - why does every class in Winforms inherit from MBRO? Well, MBRO also conveys the point that "it doesn't make sense to ever marshal me by value." This basically means that the object is somehow bound to a resource on a single machine, like an hWnd for example. So much for Windows Forms [1].

I however also remember a discussion with another speaker at one of the conference (not sure if it was Mike or Peter) in which we were talking about our opinions that the name "ProxyableObject" would have been better to convey the correct meaning. Heck, it isn't about marshalling by reference - it's about proxying. And no, I don't think that these are the same things. A MarshalByRefObject would have to be proxyable but any random proxyable object could just exist without any marshalling at all. I could simply create a proxy (i.e. a custom RealProxy), flag my class with a ProxyAttribute and see: I get a proxy instead of a real object whenever I create a new instance of the class.

So in fact, ContextBoundObject should have been called CustomProxiedObject. It's not about contexts - it's about an object supplying its own proxy. Creating or checking contexts is just the work of one very special kind of proxy. It could do many more things - like simply intercepting method calls and providing for some AOP semantics.

[1] Weird idea: maybe that's a good thing. You are normally supposed to check ctl.InvokeRequired (and if true, use ctl.Invoke() instead of directly manipulating the UI) when working with multiple threads. You could write a simple, generic proxy which you could use in front of any GUI control, and which would do this for you automatically whenever you call any method or access any property. Hey, just talking about getting rid of some code.

posted on Friday, January 24, 2003 11:45 PM

Powered by Community Server, by Telligent Systems