Search code examples
c#.net.net-remoting

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


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


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.