我一直在尝试使用以下代码在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/

10-12 14:55
查看更多