Why can't we have a class marked [Serializable] and at the same time inheriting from MarshalByRefObject?

StackOverflow https://stackoverflow.com/questions/23239628

  •  08-07-2023
  •  | 
  •  

Question

I know it sounds stupid but I am just being curious. My lecturer asked this question and we were clueless. :D

Was it helpful?

Solution

Your lecturer is incorrect.

foreach(var type in typeof(Uri).Assembly.GetTypes())
{
    if (type.IsAbstract) continue;
    if (!Attribute.IsDefined(type, typeof(SerializableAttribute))) continue;
    if (!typeof(MarshalByRefObject).IsAssignableFrom(type)) continue;
    Console.WriteLine(type.FullName);
}

shows (and note that I'm only looking at a single assembly here):

System.Media.SoundPlayer
System.Net.FileWebRequest
System.Net.FileWebResponse
System.Net.HttpWebRequest
System.Net.HttpWebResponse
System.Diagnostics.EventLogEntry

and sure enough, http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx shows:

[SerializableAttribute]
public class HttpWebRequest : WebRequest, 
    ISerializable

noting also:

[SerializableAttribute]
public abstract class WebRequest : MarshalByRefObject, 
    ISerializable

For mscorlib (typeof(object)), we get:

System.IO.Stream+SyncStream
System.IO.DirectoryInfo
System.IO.FileInfo
System.IO.MemoryStream
System.IO.TextReader+SyncTextReader
System.IO.StreamReader
System.IO.TextWriter+SyncTextWriter
System.IO.StreamWriter
System.IO.StringReader
System.IO.StringWriter
System.IO.Stream+NullStream
System.IO.TextReader+NullTextReader
System.IO.TextWriter+NullTextWriter

That's enough concrete counter-examples, I suspect.

I suspect that your lecturer is only thinking of remoting, i.e. where we expect something to either be remoted as a proxy/stub pair, or by serialization. However, this is invalid.

  • [Serializable] is also used purely for serialization purposes outside of remoting
  • remotable classes can be (and usually are) used separately-to and independently-of remoting
  • remoting is dead; tell them to stop teaching remoting, please

Or alternatively, consider:

When remoting is used, MarshalByRefObject indicates that the object should be remoted by proxy/stub - otherwise, the object needs to be serializable, so [Serializable] is required. However, the reverse is not true: [Serializable] does not mean "marshal by value" (simply: the lack of MarshalByRefObject is what means "marshal by value"). A type can be both serializable and remoted by proxy/stub. There is no conflict here.

OTHER TIPS

MarshalByRefObject is already marked as Serializable, so this may seem a bit weird.

However, this is more about logically using the tools you have. Since MarshalByRefObjects are actually accessed using proxies, they don't have a local state to serialize when you're using the proxy. That's the whole point of MarshalByRefObject. When you're using serialization, you're transferring (or saving) the state - when marshalling by reference, you're only transferring a reference to the object. So serialization is a copy, while marshal by ref is still refering to the same object, even accross application domain boundaries.

Now, as far as I know, there's actually no check to make sure the object isn't serializable - however, in practice, when it's used from outside of its application domain, there really isn't anything to serialize.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top