编辑:我个人认为下面的代码在技术上正确回答了您的问题(例如,它提供了一种在不创建副本的情况下枚举集合中的值的方法)。一些开发人员的声望远比我强烈建议反对这种方法,因为他们在编辑/cmets 中解释了原因。简而言之:这显然是个坏主意。因此我留下了答案,但建议你不要使用它。
除非我遗漏了什么,否则我相信您可以将您的值公开为IEnumerable<MyClass>,而无需使用yield 关键字复制值:
public IEnumerable<MyClass> Values {
get {
using (sync.ReadLock()) {
foreach (MyClass value in cache.Values)
yield return value;
}
}
}
但是请注意(我猜你已经知道了),这种方法提供了惰性评估,这意味着上面实现的 Values 属性可以不 被视为提供快照。
换句话说……好吧,看看这段代码(我当然猜测你这个类的一些细节):
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);
}
因此,如果要求此 Values 属性等同于访问该属性时 cache 中的内容的快照,那么您将不得不一份。
(从 280Z28 开始):以下是不熟悉“C# 做事方式”的人如何锁定代码的示例:
IEnumerator enumerator = obj.Values.GetEnumerator();
MyClass first = null;
if (enumerator.MoveNext())
first = enumerator.Current;
(结束 280Z28)