我知道这听起来很愚蠢,但我只是好奇。我的讲师问了这个问题,我们一无所知。 :d
答案 0 :(得分: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);
}
显示(并注意我只在这里查看单个程序集):
System.Media.SoundPlayer
System.Net.FileWebRequest
System.Net.FileWebResponse
System.Net.HttpWebRequest
System.Net.HttpWebResponse
System.Diagnostics.EventLogEntry
果然,http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx显示:
[SerializableAttribute]
public class HttpWebRequest : WebRequest,
ISerializable
还注意到:
[SerializableAttribute]
public abstract class WebRequest : MarshalByRefObject,
ISerializable
对于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
我怀疑那个具体反例。
我怀疑你的讲师只想到了远程处理,即我们希望 能够远程作为代理/存根对,或者通过序列化。但是,这是无效的。
[Serializable]
也仅用于远程处理之外的序列化目的或者,考虑:
使用远程处理时,MarshalByRefObject
表示该对象应由代理/存根进行远程处理 - 否则,该对象需要可序列化,因此需要[Serializable]
。然而,情况恰恰相反:[Serializable]
不意味着"按价值编组" (简单地说:缺少MarshalByRefObject
意味着"按价值编组")。类型可以通过代理/存根进行序列化和远程处理。这里没有冲突。
答案 1 :(得分:0)
MarshalByRefObject
已标记为Serializable
,因此这看起来有点奇怪。
但是,这更多是关于逻辑上使用您拥有的工具。由于MarshalByRefObject
实际上是使用代理访问的,因此当您使用代理时,它们不具有要序列化的本地状态。这是MarshalByRefObject
的重点。当您使用序列化时,您将转移(或保存)状态 - 当通过引用进行编组时,您只需要传输对象的引用。因此序列化是一个副本,而ref的编组仍然引用同一个对象,甚至是跨应用程序域边界。
现在,据我所知,实际上没有检查以确保该对象不可序列化 - 但是,实际上,当它从应用程序域外部使用时,没有什么可以序列化的。