我一直在尝试使用以下代码在AppDomain
边界上序列化数组:
public int Read(byte[] buffer, int offset, int count)
{
return base.Read(buffer, offset, count);
}
推测一下,在注意到其他属性之后,我用
[In]
和[Out]
属性标记了该方法的参数,这似乎导致这些参数的行为就像通过引用传递一样。例如:
public int Read([In, Out] byte[] buffer, int offset, int count)
{
return base.Read(buffer, offset, count);
}
在我添加属性之前,从方法跨过
buffer
边界返回后,AppDomain
变量的内容丢失了。类(
SslStream
)是从MarshalByRefObject
继承的,但未使用Serializable
属性进行标记。这是使参数传递值的唯一方法吗?在序列化类时,.NET是否会以某种方式识别这些属性?并且它们是否确实导致参数通过引用传递,还是只是复制了内容? 最佳答案
这是.NET Remoting的一个非常文献记载的功能。它的类是[Serializable]还是从MarshalByRefObject派生,这与它无关。问题在于如何在AppDomain边界上对参数进行编码。调用本身是通过Remoting在后台进行的。调用后,数组不会自动重新整理,这显然是性能优化。仅需要[Out]属性,暗含[In]。我在MSDN中找不到与此相关的任何文档,只是遇到相同问题的某个人的a blog post(向下滚动到“在远程处理中使用OutAttribute”)。
一些可玩的代码:
using System;
using System.Runtime.InteropServices;
class Program {
static void Main(string[] args) {
var ad = AppDomain.CreateDomain("second");
var t = (Test)ad.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName);
var b = new byte[] { 1 };
t.Read(b);
System.Diagnostics.Debug.Assert(b[0] == 2);
}
}
class Test : MarshalByRefObject {
public void Read([Out]byte[] arg) {
arg[0] *= 2;
}
}
关于c# - .NET中的In和Out属性如何工作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9072075/