Don't we have a lot more typesafety and a lot better intention if there would just be a keyword for lock?
It's not about type safety at all. It's about thread safety.
Sometimes that means running the same code in a single lock over and over. Perhaps you have a single large array, where some of your operations might need to swap two elements, and you want to make sure things are synchronized during the swap. In this kind of context, even a simple lock keyword by itself, where the object is created for you behind the scenes, might be good enough.
Sometimes you're sharing an object among very different sets of code. Now you need multiple lock sections that coordinate using a common object. In this case, the code you're talking about seems to make sense. Letting the compiler create a lock object for you isn't good enough because the different lock sections would not coordinate, but you also want to make sure the common lock object is fixed, and doesn't change somehow. For example, maybe you're working through an array with multiple threads, and you have different operations that might modify a shared index value that indicates which element is considered current or active. Each of these operations should lock on the same object.
But sometimes you share multiple object instances (often of the same type) among several sets of code. Think producer/consumer pattern, where multiple consumers from different threads need to coordinate access to a shared queue, and the consumers themselves are multi-threaded. In this kind of case, a single common lock object would be okay to retrieve an element from the queue, but a single shared object in different sections of the consumer could become a bottleneck for the application. Instead, you would only want to lock once per active object/consumer. You need the lock section to accept a variable that indicates which object needs protection, without locking your entire data set.
_MyLockreadonly. Don't reassign a lock object.