为什么我们不能有一个标记为[Serializable]的类,同时继承MarshalByRefObject?

Gay*_*gha 4 .net c# .net-remoting

我知道这听起来很愚蠢,但我只是好奇.我的讲师问了这个问题,我们一无所知.:d

Mar*_*ell 6

你的讲师不对.

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);
}
Run Code Online (Sandbox Code Playgroud)

显示(并注意我在这里只看一个程序集):

System.Media.SoundPlayer
System.Net.FileWebRequest
System.Net.FileWebResponse
System.Net.HttpWebRequest
System.Net.HttpWebResponse
System.Diagnostics.EventLogEntry
Run Code Online (Sandbox Code Playgroud)

果然,http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx显示:

[SerializableAttribute]
public class HttpWebRequest : WebRequest, 
    ISerializable
Run Code Online (Sandbox Code Playgroud)

还注意到:

[SerializableAttribute]
public abstract class WebRequest : MarshalByRefObject, 
    ISerializable
Run Code Online (Sandbox Code Playgroud)

对于mscorlib(typeof(object)),我们得到:

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
Run Code Online (Sandbox Code Playgroud)

我怀疑这就是具体的反例.

我怀疑你的讲师是只有想远程的,即我们期望的东西要么被远程化作为代理/存根对,或者通过序列化.但是,这是无效的.

  • [Serializable] 在远程处理之外,它也仅用于序列化目的
  • 远程类可以(通常是)单独使用,也可以独立于远程使用
  • 远程已经死了 ; 请告诉他们停止教远程教学

或者,考虑:

使用远程处理时,MarshalByRefObject表示该对象应该通过代理/存根进行远程处理 - 否则,该对象需要是可序列化的,因此[Serializable]是必需的.然而,反过来却不是这样:[Serializable] 并不意味着"按价值编组"(简单地说:缺乏MarshalByRefObject意味着"按价值编组").类型可以通过代理/存根进行序列化和远程处理.这里没有冲突.