Escribo un iterador que debe pasar un entero mutable.Contenedor mutable de tipos de valores para pasar a los iteradores
public IEnumerable<T> Foo(ref int valueThatMeansSomething)
{
// Stuff
yield return ...;
}
Esto me dice "Error 476 Los iteradores no pueden tener parámetros de ref or out".
Lo que necesito es este valor entero para ser modificado en el iterador y utilizable por la persona que llama del iterador. En otras palabras, cualquier llamada Foo()
anterior quiere saber el valor final de valueThatMeansSomething
y Foo()
puede usarlo. Realmente, quiero un entero que sea un tipo de referencia, no un tipo de valor.
Lo único que se me ocurre es escribir una clase que encapsule mi número entero y me permita modificarlo.
public class ValueWrapper<T>
where T : struct
{
public ValueWrapper(T item)
{
this.Item = item;
}
public T Item { get; set; }
}
Así:
ValueWrapper<int> w = new ValueWrapper<int>(0);
foreach(T item in Foo(w))
{
// Do stuff
}
if (w.Item < 0) { /* Do stuff */ }
¿Hay alguna clase o mecanismo para manejar esto ya en el BCL? ¿Alguna falla con ValueWrapper<T>
propuesta arriba?
(Mi uso real es más complicado que el ejemplo anterior por lo que el manejo de la variable dentro de mi foreach
bucle que llama Foo()
no es una opción. Período.)
Hacer que un campo sea volátil no es suficiente para garantizar la seguridad de las cadenas de caracteres, ya que las escrituras en tipos de valores arbitrarios no se garantiza que sean atómicas según la especificación C#. Volátil no garantiza la atomicidad, simplemente elimina algunos problemas de ordenamiento inducidos por la optimización del compilador. –
Si le importa la seguridad del hilo, use bloqueos. –
@Eric: Sí, buen punto. Originalmente escribí que garantiza la atomicidad, pero luego la eliminé rápidamente ya que me di cuenta de que esto no era necesariamente así. – Noldorin