Associating a lock/mutex with the data it protects
I confess that I think your approach looks painful. As you can see from the other answers, it's insufficient to protect your data outside the container class. And there's confusion in your example code as to whether Protected is the container or ThreadSafeCache is the container. I think instead that you need to revisit the principle of encapsulation. When you have a collection that requires multi-threaded updates and access, you protect that collection with a wrapper class. The wrapper encapsulates the underlying collection in its entirety. Think "private". If you don't want to expose the lock, then you don't expose an iterator/enumerator. Rather, you do something similar to the List's ForEach method:

public void ForEach(Action&lt;T&gt; t){
   lock(_items) foreach(var item in _items) t.Invoke(item);
}