エディテージ : Ich persönlich glaube, dass der unten stehende Code Ihre Frage technisch korrekt beantwortet (d.h. er bietet eine Möglichkeit, die Werte in einer Sammlung aufzuzählen, ohne eine Kopie zu erstellen). Einige Entwickler, die weitaus seriöser sind als ich, raten dringend gegen diesen Ansatz aus Gründen, die sie in ihren Bearbeitungen/Kommentaren erläutert haben. Kurz gesagt: Das ist offensichtlich eine schlechte Idee. Deshalb lasse ich die Antwort stehen, schlage aber vor, dass Sie sie nicht verwenden.
Wenn ich nichts übersehe, glaube ich, dass Sie Ihre Werte als eine IEnumerable<MyClass>
ohne dass Werte kopiert werden müssen, indem man die yield
Stichwort:
public IEnumerable<MyClass> Values {
get {
using (sync.ReadLock()) {
foreach (MyClass value in cache.Values)
yield return value;
}
}
}
Beachten Sie jedoch (und ich nehme an, dass Sie das bereits wussten), dass dieser Ansatz faule Bewertung was bedeutet, dass die Values
Eigenschaft, wie oben implementiert, kann no so behandelt werden, als ob sie eine Schnappschuss .
Mit anderen Worten... nun, sehen Sie sich diesen Code an (ich vermute natürlich einige Details dieser Klasse von Ihnen):
var d = new ThreadSafeDictionary<string, string>();
// d is empty right now
IEnumerable<string> values = d.Values;
d.Add("someKey", "someValue");
// if values were a snapshot, this would output nothing...
// but in FACT, since it is lazily evaluated, it will now have
// what is CURRENTLY in d.Values ("someValue")
foreach (string s in values) {
Console.WriteLine(s);
}
Wenn es also eine Voraussetzung ist, dass diese Values
Eigenschaft gleichwertig sein mit einer Schnappschuss von dem, was in cache
zum Zeitpunkt des Zugriffs auf die Immobilie, dann müssen Sie eine Kopie machen.
(Beginn 280Z28): Im Folgenden finden Sie ein Beispiel dafür, wie jemand, der mit der "C#-Methode" nicht vertraut ist, den Code sperren könnte:
IEnumerator enumerator = obj.Values.GetEnumerator();
MyClass first = null;
if (enumerator.MoveNext())
first = enumerator.Current;
(Ende 280Z28)