C # comment protéger le champ d'une classe atomique?
-
11-09-2019 - |
Question
Je suis en train de faire une classe AtomicReference en C # et je veux conserver la référence sur le terrain protégé, mais je dois aussi retourner la valeur dans la méthode get:
class AtomicReference
{
private Object _value;
public AtomicReference()
{
_value = new Object();
}
public AtomicReference(Object value)
{
OptimisticSet(value);
}
public Object CompareAndSet(Object newValue)
{
return Interlocked.Exchange(ref _value, newValue);
}
public void OptimisticSet(Object newValue)
{
do {
} while (_value == Interlocked.CompareExchange(ref _value, _value, newValue));
}
public Object Get()
{
// Don't leak the field reference
const Object constVal = _value;
return constVal;
}
}
Il est un peu maladroitement autour du problème ... Je ne peux pas rendre le champ en lecture seule, parce que je dois être en mesure de le régler. Y at-il une meilleure solution que la mienne?
Mise à jour: Merci pour les réponses rapides! Il a été à juste titre souligné que la référence sera protégé si je retourne simplement _value. Je veux aussi protéger la _value de muter. Si je laisse la _value muter en dehors du AtomicReference, il contrecarre le but de faire toute cette classe ... est-il un moyen d'y parvenir?
La solution
Même si vous essayez, il est impossible de renvoyer une référence à un champ en C # (sans code non sécurisé) ou Java. (Je ne veux pas une référence à un objet)
Vous pouvez simplement écrire return _value;
vos correspondants ne seront pas en mesure d'écrire sur le champ.
Autres conseils
C # ne supporte pas les mots clés de l 'const
C ++, ce qui permet des références immuables à des objets mutables.
Il n'y a que deux façons de faire ce que vous demandez.
- Vous pouvez cloner l'objet chaque fois que vous le retourner. Notez que cela ne fonctionne que pour les objets clonables, et ce sera assez lent.
- Vous ne pouvez supporter d'autres types de valeur.