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