Est-il possible de passer des propriétés comme “out” ou “ref” paramètres?
Puis-je passer une propriété comme une "sortie" ou "ref" paramètre si non, alors pourquoi pas?
par exemple
Person p = new Person();
.
.
.
public void Test(out p.Name);
- Veuillez entrer à nouveau la question de faire un certain sens...
- Il y a suffisamment de sens qu'il a obtenu une réponse sensée
- Salut, en fait, ma question est : puis-je passer une propriété comme une "sortie" ou "ref" paramètre si non, y a pas? exemple. Personne p = new Personne(); public void Test(p.Nom);
Vous devez vous connecter pour publier un commentaire.
Excuses pour la réponse courte, mais non, la spécification du langage C# autorise pas.
Voir ce réponse à une autre question pour voir ce qui se passe lorsque vous essayez.
Il dit aussi pourquoi vous ne devriez pas faire le bien être juste un champ public pour contourner la restriction.
Espère que cette aide
EDIT: Vous demandez Pourquoi?
Vous passer une variable à un
out
ouref
paramètre vous êtes en fait en passant l'adresse (ou lieu de mémoire) de la variable.À l'intérieur de la fonction, le compilateur sait où la variable est vraiment, et reçoit et rédige les valeurs à cette adresse.
Une propriété ressemble à une valeur, mais c'est en fait une paire de fonctions, chacune avec une signature différente. Afin de passer une propriété, vous auriez besoin de passer deux pointeurs de fonction, l'un pour l'obtenir, et un pour le jeu.
C'est une chose complètement différente de transmettre à une fonction de l'adresse d'une variable
c'est à dire une adresse de la variable v de deux pointeurs de fonction.
Mise à jour
Pourquoi ne pas en C# il suffit de regarder après cela pour nous?
Je ne suis pas Eric Lippert, mais je vais avoir un aller à pourquoi
Quelle devrait être la signature de la fonction que vous appelez être?
Disons que vous voulez l'appeler
void MyFn(ref int i)
, qui devrait rester de cette façon, ou doit-il changer le dire, nous permettent également de propriétés? Si des modifications à certains de la syntaxe commevoid MyFn(prop_ref int i)
puis c'est assez inutile, vous ne pouvez pas passer propriétés des fonctions de la bibliothèque ou de la 3e partie du code qui n'a pas été écrite avec la prop_ref modificateur. De toute façon je pense que vous êtes ce qui suggère qu'il ne devrait pas être différent.Maintenant permet de dire
MyFn
passei
à une fonction COM, ou WinAPI appel, en passant l'adresse dei
(c'est à dire à l'extérieur .net, par ref). Si c'est un bien, comment obtenez-vous l'adresse dei
? Il y a peut-être pas de réelle int en vertu de la propriété afin d'obtenir l'adresse. Ne vous faites ce que VB.Net n'?L'Vb.Net compilateur des taches quand un bien est passé comme une ByRef argument à une méthode. À ce stade, il déclare une variable, des copies de la propriété de la variable, passe la variable byref et puis, après l'appel de la méthode, des copies de la variable de retour dans la propriété. c'est à dire
devient
Tout bien effets secondaires ne se produisent pas jusqu'à ce que
MyFunc
retourne, ce qui peut causer toutes sortes de problèmes et de mener à très bogues subtils.À mon humble avis, le Vb.Net la solution à ce problème est également cassé, donc je ne vais pas accepter ça comme une réponse.
Comment pensez-vous que le compilateur C# doit gérer cela?
ref
paramètre ne doit pas être une adresse, mais en fait une paire de fermetures, un getter et un setter. Si vous passez une variable locale comme unref
paramètre, la langue doit créer automatiquement un getter/setter de la paire. Et tout cela doit être caché de la méfiance du programmeur.ref
de la propriété, tels quefoo.Location.X+=intVar;
pourrait se traduire par quelque chose d'équivalent àfoo.WorkWithBar((ref Point it, ref int dx)=>it.X += dx, ref intVar);
Noter que le Lambda ne pas fermer sur toutes les variables, de sorte qu'il doit s'exécuter rapidement, et parce queit
est unref
param, qu'elle peut mettre en place.ref
paramètre est garantie sans effets secondaires. Par exemple, une méthode peut utiliser+=
à ajouter à unref string
plusieurs fois avant de revenir, éventuellement, en vérifiant la valeur comme il va. Le programmeur de la méthode aurait besoin de savoir si son paramètre prend en charge les propriétés, car, dans ce cas, ils auraient besoin de créer une variable temporaire à la place.int Value { get; private set; }
propriétés, mais ne peut pas parce que vous ne pouvez pas passer par la réf.D'autres ont expliqué que vous ne pouvez pas le faire en C#. Dans VB.NET vous peut ce faire, même avec l'option strict/explicite sur:
Le code ci-dessus est équivalent à ce code C#:
Personnellement, je suis content que le C# n'a pas, c'est pour brouiller les cartes de beaucoup, en particulier en termes de la valeur de la propriété si le paramètre est défini dans la méthode, mais une exception est levée.
EDIT: Comme l'a demandé, mon raisonnement pour expliquer pourquoi je crois que passer des propriétés dans brouille les eaux. Si vous passez une variable normale par référence, alors que la variable est évaluée à chaque fois qu'il est référencé au sein de la méthode. Si la valeur change pour une raison quelconque (par exemple, comme un effet secondaire de certains autres travaux dans la méthode), alors que le changement sera immédiatement visible dans la méthode. Ce n'est pas le cas si vous passez une propriété par référence dans VB.NET: la propriété getter est invoquée une fois, puis la propriété setter est invoquée une fois. Ce n'est pas comme vous êtes de passage dans "voici un propriété - get et set de que chaque fois que vous utilisez le paramètre."
Voici un exemple complet d'où le passage d'un champ et passer un insignifiant propriété dans .NET ont des résultats très différents:
Une autre raison de ce n'est pas autorisé est parce que la ref et le paramètre de sortie est lisible et modifiable à l'intérieur d'une méthode, alors qu'une propriété peut être readonly/writeonly.
Maintenant, si vous pouvez faire cela?
Vous êtes maintenant pas vous, mais quelqu'un d'autre, mais c'est contre le contrat que vous avez fait avec
get
seule propriétéName
(si jamais cela a fonctionné). C'est le même cas avec readonly champs des membres de la classe, vous ne pouvez pas passer leur référence.Peut être
C#
pouvez venir avec un readonly/writeonly arguments pour une méthode:Au lieu de cela, vous devriez faire quelque chose comme ceci