NEO-146: fix remaining C# analyzer style warnings

Apply using simplification, inline declarations, const locals, and
Lock in PostgresDockerHelper; document RCS1118 and IDE0018 in style guide.
pull/187/head
VinPropane 2026-06-24 20:44:30 -04:00
parent e0877fea7f
commit b6b0b87534
6 changed files with 36 additions and 27 deletions

View File

@ -81,6 +81,18 @@ return query.ToArray();
- **Keep braced `using (var …) { … }`** when the block has **multiple statements** (Arrange + Act + Assert inside one scope, seed loops, or any sequence that shares locals). - **Keep braced `using (var …) { … }`** when the block has **multiple statements** (Arrange + Act + Assert inside one scope, seed loops, or any sequence that shares locals).
- **Do not flatten** multi-statement blocks into `using var` at method scope when inner scopes reuse names like `store`, `registry`, or `scope` — that causes **CS0136** name clashes. Use distinct names (`seedStore`, `actScope`, `readStore`) or keep the braced block. - **Do not flatten** multi-statement blocks into `using var` at method scope when inner scopes reuse names like `store`, `registry`, or `scope` — that causes **CS0136** name clashes. Use distinct names (`seedStore`, `actScope`, `readStore`) or keep the braced block.
## Local `const` (RCS1118)
- When a local is initialized from a **compile-time constant** (string literal, numeric literal, or `public const` field), declare it **`const`** instead of **`var`**.
```csharp
const string questId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId;
```
## Inline declarations (IDE0018)
- Prefer **inline initialization** over declare-then-assign when the analyzer suggests it, e.g. `var outcome = Operation(...)` and `TryGet(..., out var snapshot)` instead of separate upfront declarations.
```csharp ```csharp
// Prefer — single disposable, single follow-on statement // Prefer — single disposable, single follow-on statement
await using var conn = new NpgsqlConnection(cs); await using var conn = new NpgsqlConnection(cs);

View File

@ -85,25 +85,23 @@ public sealed class ContractOutcomePersistenceIntegrationTests(PostgresIntegrati
[], [],
RecordedAt); RecordedAt);
using (var scope = Factory.Services.CreateScope()) using var scope = Factory.Services.CreateScope();
{ var instanceStore = scope.ServiceProvider.GetRequiredService<IContractInstanceStore>();
var instanceStore = scope.ServiceProvider.GetRequiredService<IContractInstanceStore>(); var outcomeStore = scope.ServiceProvider.GetRequiredService<IContractOutcomeStore>();
var outcomeStore = scope.ServiceProvider.GetRequiredService<IContractOutcomeStore>(); Assert.True(instanceStore.TryCreateActive(
Assert.True(instanceStore.TryCreateActive( PlayerId,
PlayerId, InstanceId,
InstanceId, TemplateId,
TemplateId, SeedBucket,
SeedBucket, IssuedAt,
IssuedAt, out _));
out _)); Assert.True(outcomeStore.TryAppend(outcomeRow));
Assert.True(outcomeStore.TryAppend(outcomeRow)); // Act
// Act var duplicateId = outcomeStore.TryAppend(outcomeRow with { IdempotencyKey = "other-key" });
var duplicateId = outcomeStore.TryAppend(outcomeRow with { IdempotencyKey = "other-key" }); var duplicateKey = outcomeStore.TryAppend(outcomeRow with { Id = "outcome-row-pg-002" });
var duplicateKey = outcomeStore.TryAppend(outcomeRow with { Id = "outcome-row-pg-002" }); // Assert
// Assert Assert.False(duplicateId);
Assert.False(duplicateId); Assert.False(duplicateKey);
Assert.False(duplicateKey);
}
} }
[RequirePostgresFact] [RequirePostgresFact]

View File

@ -57,14 +57,12 @@ public sealed class ResourceNodeInstancePersistenceIntegrationTests(PostgresInte
} }
// Act // Act
ResourceNodeInstanceMutationOutcome denyOutcome;
ResourceNodeInstanceSnapshot persisted;
await using var secondFactory = new PostgresWebApplicationFactory(); await using var secondFactory = new PostgresWebApplicationFactory();
using var actScope = secondFactory.Services.CreateScope(); using var actScope = secondFactory.Services.CreateScope();
var actRegistry = actScope.ServiceProvider.GetRequiredService<IResourceNodeDefinitionRegistry>(); var actRegistry = actScope.ServiceProvider.GetRequiredService<IResourceNodeDefinitionRegistry>();
var actStore = actScope.ServiceProvider.GetRequiredService<IResourceNodeInstanceStore>(); var actStore = actScope.ServiceProvider.GetRequiredService<IResourceNodeInstanceStore>();
denyOutcome = ResourceNodeInstanceOperations.TryCommitSuccessfulGatherDecrement(AlphaId, actRegistry, actStore); var denyOutcome = ResourceNodeInstanceOperations.TryCommitSuccessfulGatherDecrement(AlphaId, actRegistry, actStore);
actStore.TryGetRemainingGathers(AlphaId, out persisted); actStore.TryGetRemainingGathers(AlphaId, out var persisted);
// Assert // Assert
Assert.Equal(ResourceNodeInstanceMutationKind.Denied, denyOutcome.Kind); Assert.Equal(ResourceNodeInstanceMutationKind.Denied, denyOutcome.Kind);

View File

@ -1,4 +1,5 @@
using System.Diagnostics; using System.Diagnostics;
using System.Threading;
using Npgsql; using Npgsql;
namespace NeonSprawl.Server.Tests.Game.PositionState; namespace NeonSprawl.Server.Tests.Game.PositionState;
@ -13,7 +14,7 @@ namespace NeonSprawl.Server.Tests.Game.PositionState;
/// </remarks> /// </remarks>
internal static class PostgresDockerHelper internal static class PostgresDockerHelper
{ {
private static readonly object StateLock = new(); private static readonly Lock StateLock = new();
private static Task? _ensureTask; private static Task? _ensureTask;
private static bool _composeStartedByUs; private static bool _composeStartedByUs;
private static string? _repoRoot; private static string? _repoRoot;

View File

@ -22,7 +22,7 @@ public sealed class PlayerQuestProgressPersistenceIntegrationTests(PostgresInteg
// Arrange // Arrange
await ResetQuestProgressTableAsync(); await ResetQuestProgressTableAsync();
const int concurrentCalls = 8; const int concurrentCalls = 8;
var questId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId; const string questId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId;
// Act // Act
var results = await Task.WhenAll( var results = await Task.WhenAll(
@ -93,7 +93,7 @@ public sealed class PlayerQuestProgressPersistenceIntegrationTests(PostgresInteg
{ {
// Arrange // Arrange
await ResetQuestProgressTableAsync(); await ResetQuestProgressTableAsync();
var questId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId; const string questId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId;
// Act // Act
using (var firstScope = Factory.Services.CreateScope()) using (var firstScope = Factory.Services.CreateScope())

View File

@ -107,7 +107,7 @@ public static class PrototypeE7M3QuestFactionRules
/// <summary>Returns a human-readable error if grid contract quest shape fails, otherwise <see langword="null"/>.</summary> /// <summary>Returns a human-readable error if grid contract quest shape fails, otherwise <see langword="null"/>.</summary>
public static string? TryGetGridContractShapeError(IReadOnlyDictionary<string, QuestDefRow> rowsById) public static string? TryGetGridContractShapeError(IReadOnlyDictionary<string, QuestDefRow> rowsById)
{ {
var qid = PrototypeE7M1QuestCatalogRules.GridContractQuestId; const string qid = PrototypeE7M1QuestCatalogRules.GridContractQuestId;
if (!rowsById.TryGetValue(qid, out var row)) if (!rowsById.TryGetValue(qid, out var row))
return $"error: missing quest '{qid}'"; return $"error: missing quest '{qid}'";