I just had to deal with this as well, and was having the same trouble that @mpelzer was, but I think I figured out the underlying issue. What apparently happens is that the LayerTable indexer returns a new Layer object each time it’s invoked (that is, Object.ReferenceEquals(doc.Layers, doc.Layers) returns false). So that means that this, for example, is just a series of effective no-ops:
doc.Layers.IsVisible = false; // Create new Layer object, set IsVisible to false, throw it away
doc.Layers.SetPersistentVisibility(false); // Create new Layer object, set persistent visibility to false, throw it away
doc.Layers.CommitChanges(); // Create new Layer object, commit (nonexistent) changes
Since @dale’s solution stored the retrieved Layer object in an intermediate variable, it doesn’t have this problem, and when I changed my code to do that, it started working.