RemoteObj obj = (RemoteObj)Activator.GetObject(typeof(RemoteObj), "http://localhost:2222/remoteobj");

// Prints "does not work"

Console.WriteLine("Remote: Equals " + (obj.Equals(obj) ? "works" : "does not work"));

 

There's a very logical explination for this behavior:

When you call Equals() on the __TransparentProxy for your remoting object the call is actually getting forwarded to your remoted object. Inside of your remoted object Equals is called with the parameter that was passed in which in this case is a __TransparentProxy. So, Equals compares your RemoteObject with __TransparentProxy and determines that the two objects are not the same.

You can verify that this is the case simply by overriding Equals in your remote object, put a breakpoint there and see that this = RemotingObject and obj = __TransparentProxy.  When comparing these objects they are not the same and Equals returns false.