In 和 Out 属性在 .NET 中如何工作? [英] How do the In and Out attributes work in .NET?

查看:16
本文介绍了In 和 Out 属性在 .NET 中如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been trying to serialize an array across an AppDomain boundary, using the following code:

public int Read(byte[] buffer, int offset, int count)
{
    return base.Read(buffer, offset, count);
}

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

As a guess, after noticing the attributes elsewhere, I marked the method's parameters with [In] and [Out] attributes, which seemed to cause the parameters to behave as if they were passed by reference.

例如:

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

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

Before I added the attributes, the contents of the buffer variable were lost after returning from the method across an AppDomain boundary.

类 (SslStream) 继承自 MarshalByRefObject,但未使用 Serializable 属性进行标记.这是使参数按值传递的唯一方法吗?当类被序列化时,.NET 是否会以某种方式识别这些属性?并且他们真的导致参数通过引用传递,还是只是复制了内容?

The class (SslStream) was inheriting from MarshalByRefObject but not marked with the Serializable attribute. Is this the only way to make a parameter pass-by-value? Are these attributes being recognised somehow by .NET when the class is being serialised? And do they truly cause the parameter to be passed by reference, or are the contents just copied?

推荐答案

这是 .NET Remoting 的一个非常糟糕的记录功能.它与您的类是 [Serializable] 还是从 MarshalByRefObject 派生无关.这里的问题是如何跨 AppDomain 边界封送 argument.调用本身是由 Remoting 在后台进行的.数组在调用后不会自动被编组回来,这显然是一种性能优化.只有 [Out] 属性是必需的,[In] 是隐含的.我在 MSDN 中找不到任何相关文档,只是 一篇博文 来自遇到相同问题的人(向下滚动到在远程处理中使用 OutAttribute").

This is a remarkably poorly documented feature of .NET Remoting. It doesn't have anything to do with whether your class is [Serializable] or derived from MarshalByRefObject. At issue here is how the argument is marshaled across the AppDomain boundary. The call itself is made under the hood by Remoting. Arrays do not automatically get marshaled back after the call, clearly a performance optimization. Only the [Out] attribute is required, [In] is implied. I could not find any relevant documentation about this in MSDN, just a blog post from somebody that ran into the same issue (scroll down to "Using OutAttribute in Remoting").

一些代码:

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;
    }
}

这篇关于In 和 Out 属性在 .NET 中如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆