Maison >développement back-end >C++ >Pourquoi la transmission de valeurs aux champs de classe par référence ne fonctionne-t-elle pas en C# et comment puis-je obtenir un comportement similaire ?
En C#, il peut sembler que l'attribution de valeurs aux champs de classe par référence peut être réalisée à l'aide de la ref modificateur de paramètre. Cependant, cette technique ne parvient pas à préserver la référence lors de l'affectation à un champ.
Considérez l'extrait de code suivant :
public class X { public X() { string example = "X"; new Y(ref example); new Z(ref example); System.Diagnostics.Debug.WriteLine(example); } } public class Y { public Y(ref string example) { example += " (Updated By Y)"; } } public class Z { private string _Example; public Z(ref string example) { this._Example = example; this._Example += " (Updated By Z)"; } } var x = new X();
Le résultat attendu est de voir les deux mises à jour ont été appliquées à la chaîne : "X (mis à jour par Y) (mis à jour par Z)" mais la sortie réelle est uniquement "X (mis à jour par Y)". Cela soulève la question de savoir comment conserver la référence lors de l'affectation à un champ.
La limitation vient du fait que C# n'autorise pas les champs de type ref. Cette contrainte oblige à choisir entre interdire complètement les champs ref ou autoriser les champs non sécurisés qui pourraient potentiellement conduire à des plantages. De plus, l'utilisation du pool de stockage temporaire pour les variables locales (la pile) entrerait en conflit avec l'accès à des valeurs qui pourraient ne plus exister une fois la méthode terminée.
Pour éviter ces problèmes, C# interdit les champs ref et recommande d'utiliser méthodes getter et setter à la place :
sealed class Ref<T> { private readonly Func<T> getter; private readonly Action<T> setter; public Ref(Func<T> getter, Action<T> setter) { this.getter = getter; this.setter = setter; } public T Value { get { return getter(); } set { setter(value); } } } ... Ref<int> x; void M() { int y = 123; x = new Ref<int>(() => y, z => { y = z; }); x.Value = 456; Console.WriteLine(y); // 456 -- setting x.Value changes y. }
En utilisant cette approche, x devient effectivement un objet qui a la capacité d'obtenir et de définir la valeur de y, même si y est stocké sur le tas récupéré.
Bien que C# ne prenne pas directement en charge le retour des références méthodes et paramètres ref, cette fonctionnalité a été implémentée dans C# 7. Cependant, le fait que les types ref ne peuvent pas être utilisés comme champs reste une limitation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!