diff --git a/src/Meziantou.Analyzer/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzer.cs b/src/Meziantou.Analyzer/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzer.cs index 3afab307d..d5b4dd189 100644 --- a/src/Meziantou.Analyzer/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzer.cs +++ b/src/Meziantou.Analyzer/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzer.cs @@ -99,6 +99,10 @@ private void HandleOperation(ISymbol symbol, IOperation operation) if (!IsPotentialSymbol(symbol)) return; + // Assignment targets (e.g., initializations in constructors) are not usages + if (operation.Parent is IAssignmentOperation { Target: var assignTarget } && assignTarget == operation) + return; + if (operation.Parent is not ILockOperation) { ExcludeSymbol(symbol); diff --git a/tests/Meziantou.Analyzer.Test/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzerTests.cs b/tests/Meziantou.Analyzer.Test/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzerTests.cs index d5836c02d..fc0f6473e 100644 --- a/tests/Meziantou.Analyzer.Test/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzerTests.cs +++ b/tests/Meziantou.Analyzer.Test/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzerTests.cs @@ -260,5 +260,99 @@ void A() """) .ValidateAsync(); } + + [Fact] + public async Task Field_InitializedInConstructor_OnlyLockUsage() + { + await CreateProjectBuilder() + .WithSourceCode(""" + public sealed class A + { + private readonly object [||]_lock; + + public A() + { + _lock = new object(); + } + + public void Run() + { + lock (_lock) { } + } + } + """) + .ValidateAsync(); + } + + [Fact] + public async Task Field_InitializedInConstructor_LockAndOtherUsages() + { + await CreateProjectBuilder() + .WithSourceCode(""" + public sealed class A + { + private readonly object _lock; + + public A() + { + _lock = new object(); + } + + public void Run() + { + lock (_lock) { } + _lock.ToString(); + } + } + """) + .ValidateAsync(); + } + + [Fact] + public async Task StaticField_InitializedInStaticConstructor_OnlyLockUsage() + { + await CreateProjectBuilder() + .WithSourceCode(""" + public sealed class B + { + private static readonly object [||]Lock; + + static B() + { + Lock = new object(); + } + + public void Run() + { + lock (Lock) { } + } + } + """) + .ValidateAsync(); + } + + [Fact] + public async Task StaticField_InitializedInStaticConstructor_LockAndOtherUsages() + { + await CreateProjectBuilder() + .WithSourceCode(""" + public sealed class B + { + private static readonly object Lock; + + static B() + { + Lock = new object(); + } + + public void Run() + { + lock (Lock) { } + Lock.ToString(); + } + } + """) + .ValidateAsync(); + } #endif }