Comment les atsortingbuts In et Out fonctionnent-ils dans .NET?

J’ai essayé de sérialiser un tableau à travers une limite AppDomain utilisant le code suivant:

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

Je suppose que, après avoir remarqué les atsortingbuts ailleurs, j’ai marqué les parameters de la méthode avec les atsortingbuts [In] et [Out] , ce qui a semblé provoquer le comportement des parameters comme s’ils étaient passés par référence.

Par exemple:

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

Avant d’append les atsortingbuts, le contenu de la variable de buffer était perdu après le retour de la méthode AppDomain une limite AppDomain .

La classe ( SslStream ) héritait de MarshalByRefObject mais n’était pas marquée avec l’atsortingbut Serializable . Est-ce la seule façon de faire passer un paramètre par valeur? Est-ce que ces atsortingbuts sont reconnus d’une manière ou d’une autre par .NET lorsque la classe est en cours de sérialisation? Et font-ils vraiment que le paramètre soit passé par référence ou est-ce que le contenu est simplement copié?

Il s’agit d’une fonctionnalité remarquablement mal documentée de .NET Remoting. Cela n’a rien à voir avec le fait que votre classe soit [Serializable] ou dérivée de MarshalByRefObject. La question est de savoir comment l’ argument est marshalé à travers la limite AppDomain. L’appel lui-même est fait sous le capot par Remoting. Les tableaux ne sont pas automatiquement marshalés après l’appel, ce qui constitue clairement une optimisation des performances. Seul l’atsortingbut [Out] est requirejs, [In] est impliqué. Je ne trouvais aucune documentation pertinente à ce sujet dans MSDN, mais simplement un article de blog rédigé par quelqu’un qui rencontrait le même problème (faites défiler jusqu’à “Utilisation de OutAtsortingbute dans la communication à distance”).

Quelques codes pour jouer avec:

 using System; using System.Runtime.InteropServices; class Program { static void Main(ssortingng[] 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; } }