Sto scrivendo un iteratore che deve passare attorno a un intero mutabile.Involucro mutabile di tipi di valori da passare negli iteratori
public IEnumerable<T> Foo(ref int valueThatMeansSomething)
{
// Stuff
yield return ...;
}
Questo mi cattura con la rete "Errore 476 Iteratori non possono avere rif o fuori dei parametri".
Quello che mi serve è che questo valore intero sia modificato nell'iteratore e utilizzabile dal chiamante dell'iteratore. In altre parole, qualunque chiamata Foo()
sopra vuole conoscere il valore finale di valueThatMeansSomething
e Foo()
può utilizzarlo. In realtà, voglio un intero che è un tipo di riferimento e non un tipo di valore.
L'unica cosa a cui riesco a pensare è scrivere una classe che incapsula il mio intero e mi consente di modificarlo.
public class ValueWrapper<T>
where T : struct
{
public ValueWrapper(T item)
{
this.Item = item;
}
public T Item { get; set; }
}
Quindi:
ValueWrapper<int> w = new ValueWrapper<int>(0);
foreach(T item in Foo(w))
{
// Do stuff
}
if (w.Item < 0) { /* Do stuff */ }
C'è qualsiasi classe o di un meccanismo per gestire questo già nel BCL? Eventuali difetti con ValueWrapper<T>
proposti sopra?
(mio uso effettivo è più complicata di quanto l'esempio di cui sopra in modo da gestire la variabile dentro la mia foreach
ciclo che chiama Foo()
non è un'opzione. Periodo.)
La creazione di un campo volatile non è sufficiente per garantire la sicurezza dei thread, in quanto la scrittura di tipi di valori arbitrari non è garantita dalla specifica C#. Volatile non garantisce l'atomicità, elimina solo alcuni problemi di ordinamento indotti dall'ottimizzazione del compilatore. –
Se ti interessa la sicurezza del filo, usa le serrature. –
@Eric: Sì, buon punto. Originariamente ho scritto che garantisce l'atomicità, ma poi l'ho rimosso rapidamente quando ho capito che non erano necessariamente i casi. – Noldorin