Ich schreibe einen Iterator, der eine veränderliche Ganzzahl übergeben muss.Veränderlicher Wrapper von Werttypen, die an Iteratoren übergeben werden können
public IEnumerable<T> Foo(ref int valueThatMeansSomething)
{
// Stuff
yield return ...;
}
Dies ordnet mich "Error 476 Iteratoren können ref oder out Parameter nicht haben".
Was ich brauche, ist dieser Integerwert, der im Iterator geändert und vom Aufrufer des Iterators verwendet werden kann. Mit anderen Worten, was immer Foo()
anruft, möchte den Endwert von valueThatMeansSomething
und Foo()
auch selbst verwenden. Wirklich, ich möchte eine Ganzzahl, die ein Referenztyp ist, kein Werttyp.
Ich kann nur an eine Klasse denken, die meine Ganzzahl kapselt und mir erlaubt, sie zu ändern.
public class ValueWrapper<T>
where T : struct
{
public ValueWrapper(T item)
{
this.Item = item;
}
public T Item { get; set; }
}
So:
ValueWrapper<int> w = new ValueWrapper<int>(0);
foreach(T item in Foo(w))
{
// Do stuff
}
if (w.Item < 0) { /* Do stuff */ }
Gibt es eine Klasse oder einen Mechanismus dies bereits in der BCL zu behandeln? Irgendwelche Fehler mit ValueWrapper<T>
oben vorgeschlagen?
(Meine tatsächliche Nutzung ist komplizierter als das obige Beispiel so die Variable in meiner foreach
Schleife der Handhabung Foo()
Anrufe ist keine Option. Period.)
Wenn Sie ein flüchtiges Feld erstellen, ist dies nicht ausreichend, um die Threadsicherheit zu gewährleisten, da die C# -Spezifikation nicht garantiert, dass Schreibvorgänge auf beliebige Werttypen atomar sind. Volatile garantiert keine Atomizität, es eliminiert nur einige Probleme, die durch die Optimierung der Compiler verursacht werden. –
Wenn Sie sich für die Sicherheit von Gewinden interessieren, verwenden Sie Schlösser. –
@Eric: Ja, guter Punkt. Ich schrieb ursprünglich, dass es Atomarität garantiert, aber dann schnell entfernte es, als ich erkannte, dass dies nicht unbedingt die Fälle war. – Noldorin