9
votes

Passer une mise en forme explicite sous forme de paramètre refer (c #)

J'ai une classe qui est principalement une enveloppe pour un grand tableau et un entretien de ménage associé. J'ai une fonction qui prend un paramètre Réf. Lorsque je passe une instance de la classe dans la fonction, je veux que le tableau soit envoyé.

J'ai considéré comme des moulages explicites. Disons que j'ai une fonction qui a un paramètre d'octet [] ref. P> xxx pré>

et que j'ai une classe avec une distribution explicite surchargée. P>

    SomeClass someInstance = new SomeClass();
    SomeFunction(ref (byte[]) someInstance);


0 commentaires

4 Réponses :


9
votes

Un casting n'est pas une variable assignable; Vous passez une valeur de retour à partir de votre opérateur de distribution explicite.

Vous pouvez créer une variable tenant la valeur appropriée avant de le transmettre comme référence: xxx

Notez que Il est maintenant la variable partanbytes qui peut être réaffectée. Vous devrez prendre des mesures pour réaffecter quelqueinstance.somebytes d'une manière ou d'une autre après l'appel à de fonctionnement si vous souhaitez la valeur interne du une certaine phrase pour être réaffecté.


2 commentaires

Il s'avère donc que la solution pratique serait soit un domaine public, soit une méthode courte dont le seul but est de couvrir la création de certaines variables locales à passer. J'ai fait de plus en plus de creusement et de génériques pourraient également aider.


Droite, un constructeur simple suffirait à la mise à jour de la peine. À titre de alternative, vous pouvez créer une interface que l'assignation de fonctionnement prend une argumentation et une autre implémente et met en œuvre votre logique via cette interface.



1
votes

Vous ne pouvez pas faire cela, vous devez conclure le résultat de la coulée de votre objet dans une variable d'abord.

Considérez le code suivant, si ce que vous demandez était autorisé: P>

public void SomeFunction(ref byte[] someBytes)
{
    someBytes = new byte[] { 1, 2, 3 };
}

SomeClass someInstance = new SomeClass();
SomeFunction(ref (byte[]) someInstance);
// uh-oh, what is "someInstance" now?


3 commentaires

L'argument est marqué Réfléchir probablement parce que le développeur tiers original portant une bibliothèque C ++ à .NET. Le problème que j'essaye de résoudre est de danser autour de la référence sans faire un champ public ou créer la variable locale. J'ai choisi la "Cast explicite" car je savais que les champs de ménage seraient perdus. J'espérais que certaines personnes seraient simplement transmettre la référence à l'USBBYtes à une certaine pression. Pas très différent de l'utilisation d'un domaine public, mais obligerait des moulages explicites le rendrait moins sujette à l'abus.


Eh bien, "Réf" et "Out" Les paramètres nécessitent une variable de support, il n'y a vraiment aucun moyen de cela, vous devez donc simplement définir la variable comme vous l'avez déjà découvert. Vous pouvez bien sûr faire des méthodes de shim dans une classe de votre choix pour simplement faire cette traduction pour vous et appelez plutôt ces méthodes, qui feraient à son tour la distribution, stocker dans une variable et appeler les méthodes actuelles, mais cela pourrait ne pas être une bonne solution non plus.


La solution finale implique en réalité la création d'une copie locale de la référence à l'octet [] et de référer cette copie locale. Ceci influence techniquement le point de Ref, mais je suis à peu près sûr que le programmeur tiers pensait que Ref in c # était la même que et en C ++ et ce n'est pas vrai.



1
votes

La portée des valeurs pouvant être utilisées en tant que paramètre Réf dans C # est limitée par ce que le CLR permet. Il est spécifié dans la spécification CLI aux sections 12.4.1.5.2 et 12.1.6.1 et comprend

  • argument de la méthode actuelle
  • Variable locale
  • champ membre d'un objet
  • Champ statique
  • élément de tableau

    Un casting ne correspond à aucun de ces éléments et ne peut donc pas être utilisé comme valeur ref . Vous devrez l'affecter à une valeur comme un local avant de la transmettre par référence.


1 commentaires

Merci pour la référence à la spécification! Je ne suis pas entré dans C # pendant un moment, de sorte que cela était une question plus académique, car j'explore pleinement les différentes caractéristiques de la langue ... et il y en a bien.



0
votes

Devez-vous vraiment lancer le paramètre ref? Dans mon cas, quelque chose comme ça fonctionne bien. XXX


0 commentaires