In和Out属性如何在.NET中运行?

g t*_*g t 10 c# parameters serialization attributes marshalbyrefobject

我一直在尝试AppDomain使用以下代码跨越边界序列化数组:

public int Read(byte[] buffer, int offset, int count)
{
    return base.Read(buffer, offset, count);
}
Run Code Online (Sandbox Code Playgroud)

作为一个猜测,在注意到其他地方的属性之后,我用方法[In][Out]属性标记了方法的参数,这似乎导致参数的行为就好像它们是通过引用传递的一样.

例如:

public int Read([In, Out] byte[] buffer, int offset, int count)
{
    return base.Read(buffer, offset, count);
}
Run Code Online (Sandbox Code Playgroud)

在添加属性之前,buffer从方法跨越AppDomain边界返回后,变量的内容会丢失.

class(SslStream)继承自MarshalByRefObject但未标记Serializable属性.这是使参数按值传递的唯一方法吗?在序列化类时,这些属性是否被.NET以某种方式识别?它们是否真的导致参数通过引用传递,或者内容是否被复制?

Han*_*ant 12

这是.NET Remoting的一个非常难以记录的功能.它与您的类是[Serializable]还是从MarshalByRefObject派生无关.这里的问题是如何在AppDomain边界编组参数.呼叫本身是由Remoting引起的.在调用之后,数组不会自动被编组,显然是性能优化.只需要[Out]属性,暗示[In].我在MSDN中找不到关于此的任何相关文档,只是来自遇到同一问题的某人的博客文章(向下滚动到"在Remoting中使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 进一步检查,System命名空间中的许多Stream类确实具有用[In] [Out]属性标记的Read()方法的'buffer'参数.我想知道System.IO中的NegotiateStream和SslStream是否也应该具有这些属性,因为它们在.NET 4中不存在. (2认同)