在C#中,类实例是引用类型.这是否意味着锁定返回的值的副本是可以的new?在我的例子中,我有一个类,其中包含一些需要锁定的字段:
class Foo {
// ...
private Dictionary<IAsyncResult, string> fReadRequests;
private Dictionary<IAsyncResult, string> fWriteRequests;
private Dictionary<IAsyncResult, string> fSyncRequests;
}
Run Code Online (Sandbox Code Playgroud)
在特定方法中,我需要对所有这些字段执行相同的操作.因此,为了避免代码重复,我通过将字段复制到数组中来循环执行操作:
var dictArray = new[] { fReadRequests, fWriteRequests, fSyncRequests };
foreach (var reqDict in dictArray) {
lock (reqDict) {
foreach (var i in reqDict) {
// Do something with the request.
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样安全吗?即使应用了锁的变量是原始的副本,锁定是否按预期工作?
是的,你永远不会锁定包含引用的变量,你总是锁定实例.
在您的情况下,您正在复制引用,而不是对象,因此它与您正在处理的那些字段中的对象相同.
锁定那些应该工作得很好.
只要知道:
object变量中也是如此.每次将值类型复制到object变量中时,都会获得一个新副本,该副本将具有自己的锁定.抵消nbr.2你通常这样做:
private readonly object fLockReadQuests = new object();
Run Code Online (Sandbox Code Playgroud)
然后锁定它.
但同样,你在问题中的假设仍然存在.