From 9ce1fa630cd68827054f6757001cc598897e1e2c Mon Sep 17 00:00:00 2001 From: gewuyou <95328647+GeWuYou@users.noreply.github.com> Date: Sat, 25 Apr 2026 10:38:48 +0800 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=E6=94=B6=E6=95=9B=20Core=20?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E4=B8=8E=E6=B5=8B=E8=AF=95=E7=9A=84=E6=9C=BA?= =?UTF-8?q?=E6=A2=B0=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 ContextAware、Store 与通用扩展中的参数空校验写法以满足 analyzer 约束 - 简化 coroutine、pause、log 与 async 测试中的等待和断言包装并保持测试语义不变 - 调整测试替身异常类型与 Result 系列断言样例以减少低风险 warning 噪音 --- ...ArchitectureAdditionalCqrsHandlersTests.cs | 11 ++- .../RegistryInitializationHookBaseTests.cs | 68 ++++++++-------- .../CommandCoroutineExtensionsTests.cs | 79 ++++++++++--------- .../Coroutine/TaskCoroutineExtensionsTests.cs | 10 +-- .../Coroutine/WaitForTaskTTests.cs | 12 +-- .../Extensions/AsyncExtensionsTests.cs | 34 ++++---- .../Functional/ResultTTests.cs | 14 ++-- .../Logging/LogContextTests.cs | 10 +-- .../Pause/PauseStackManagerTests.cs | 6 +- GFramework.Core/Extensions/AsyncExtensions.cs | 21 ++++- .../Extensions/CollectionExtensions.cs | 33 ++++++-- .../ContextAwareCommandExtensions.cs | 44 +++++++++-- .../ContextAwareEnvironmentExtensions.cs | 14 +++- .../Extensions/ContextAwareEventExtensions.cs | 41 ++++++++-- .../Extensions/ContextAwareQueryExtensions.cs | 22 +++++- .../ContextAwareServiceExtensions.cs | 79 +++++++++++++++---- GFramework.Core/Extensions/GuardExtensions.cs | 13 ++- .../Extensions/NumericExtensions.cs | 11 ++- .../Extensions/StoreEventBusExtensions.cs | 35 ++++++-- .../Extensions/StringExtensions.cs | 16 ++-- .../StateManagement/StoreBuilder.cs | 14 +++- .../StateManagement/StoreSelection.cs | 15 ++-- 22 files changed, 411 insertions(+), 191 deletions(-) diff --git a/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs b/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs index ddec08c8..f191863d 100644 --- a/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs +++ b/GFramework.Core.Tests/Architectures/ArchitectureAdditionalCqrsHandlersTests.cs @@ -174,8 +174,15 @@ internal sealed class AdditionalAssemblyNotificationHandlerRegistry : ICqrsHandl /// public void Register(IServiceCollection services, ILogger logger) { - ArgumentNullException.ThrowIfNull(services); - ArgumentNullException.ThrowIfNull(logger); + if (services is null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (logger is null) + { + throw new ArgumentNullException(nameof(logger)); + } services.AddTransient>(_ => CreateHandler()); logger.Debug( diff --git a/GFramework.Core.Tests/Architectures/RegistryInitializationHookBaseTests.cs b/GFramework.Core.Tests/Architectures/RegistryInitializationHookBaseTests.cs index 6882ced4..4fdb4398 100644 --- a/GFramework.Core.Tests/Architectures/RegistryInitializationHookBaseTests.cs +++ b/GFramework.Core.Tests/Architectures/RegistryInitializationHookBaseTests.cs @@ -168,52 +168,52 @@ public class TestArchitectureWithRegistry : IArchitecture T IArchitecture.RegisterSystem(T system) { - throw new NotImplementedException(); + throw new NotSupportedException(); } T IArchitecture.RegisterModel(T model) { - throw new NotImplementedException(); + throw new NotSupportedException(); } T IArchitecture.RegisterUtility(T utility) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterCqrsPipelineBehavior() where TBehavior : class { - throw new NotImplementedException(); + throw new NotSupportedException(); } /// /// 测试替身未实现显式程序集 CQRS 处理器接入入口。 /// /// 包含 CQRS 处理器或生成注册器的程序集。 - /// 该测试替身不参与 CQRS 程序集接入路径验证。 + /// 该测试替身不参与 CQRS 程序集接入路径验证。 public void RegisterCqrsHandlersFromAssembly(Assembly assembly) { - throw new NotImplementedException(); + throw new NotSupportedException(); } /// /// 测试替身未实现显式程序集 CQRS 处理器接入入口。 /// /// 要接入的程序集集合。 - /// 该测试替身不参与 CQRS 程序集接入路径验证。 + /// 该测试替身不参与 CQRS 程序集接入路径验证。 public void RegisterCqrsHandlersFromAssemblies(IEnumerable assemblies) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public IArchitectureModule InstallModule(IArchitectureModule module) { - throw new NotImplementedException(); + throw new NotSupportedException(); } IArchitectureLifecycleHook IArchitecture.RegisterLifecycleHook(IArchitectureLifecycleHook hook) { - throw new NotImplementedException(); + throw new NotSupportedException(); } Task IArchitecture.WaitUntilReadyAsync() @@ -223,17 +223,17 @@ public class TestArchitectureWithRegistry : IArchitecture public void RegisterUtility(Action? onCreated = default(Action?)) where T : class, IUtility { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterModel(Action? onCreated = default(Action?)) where T : class, IModel { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterSystem(Action? onCreated = default(Action?)) where T : class, ISystem { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void Initialize() @@ -242,7 +242,7 @@ public class TestArchitectureWithRegistry : IArchitecture public void Destroy() { - throw new NotImplementedException(); + throw new NotSupportedException(); } Task IAsyncInitializable.InitializeAsync() @@ -257,7 +257,7 @@ public class TestArchitectureWithRegistry : IArchitecture public Task WaitUntilReadyAsync() { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterLifecycleHook(IArchitectureLifecycleHook hook) @@ -266,12 +266,12 @@ public class TestArchitectureWithRegistry : IArchitecture public Task InitializeAsync() { - throw new NotImplementedException(); + throw new NotSupportedException(); } public ValueTask DestroyAsync() { - throw new NotImplementedException(); + throw new NotSupportedException(); } } @@ -313,72 +313,72 @@ public class TestArchitectureWithoutRegistry : IArchitecture T IArchitecture.RegisterSystem(T system) { - throw new NotImplementedException(); + throw new NotSupportedException(); } T IArchitecture.RegisterModel(T model) { - throw new NotImplementedException(); + throw new NotSupportedException(); } T IArchitecture.RegisterUtility(T utility) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterCqrsPipelineBehavior() where TBehavior : class { - throw new NotImplementedException(); + throw new NotSupportedException(); } /// /// 测试替身未实现显式程序集 CQRS 处理器接入入口。 /// /// 包含 CQRS 处理器或生成注册器的程序集。 - /// 该测试替身不参与 CQRS 程序集接入路径验证。 + /// 该测试替身不参与 CQRS 程序集接入路径验证。 public void RegisterCqrsHandlersFromAssembly(Assembly assembly) { - throw new NotImplementedException(); + throw new NotSupportedException(); } /// /// 测试替身未实现显式程序集 CQRS 处理器接入入口。 /// /// 要接入的程序集集合。 - /// 该测试替身不参与 CQRS 程序集接入路径验证。 + /// 该测试替身不参与 CQRS 程序集接入路径验证。 public void RegisterCqrsHandlersFromAssemblies(IEnumerable assemblies) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public IArchitectureModule InstallModule(IArchitectureModule module) { - throw new NotImplementedException(); + throw new NotSupportedException(); } IArchitectureLifecycleHook IArchitecture.RegisterLifecycleHook(IArchitectureLifecycleHook hook) { - throw new NotImplementedException(); + throw new NotSupportedException(); } public Task WaitUntilReadyAsync() { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterUtility(Action? onCreated = default(Action?)) where T : class, IUtility { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterModel(Action? onCreated = default(Action?)) where T : class, IModel { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterSystem(Action? onCreated = default(Action?)) where T : class, ISystem { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void Initialize() @@ -387,17 +387,17 @@ public class TestArchitectureWithoutRegistry : IArchitecture public Task InitializeAsync() { - throw new NotImplementedException(); + throw new NotSupportedException(); } public ValueTask DestroyAsync() { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void Destroy() { - throw new NotImplementedException(); + throw new NotSupportedException(); } public void RegisterLifecycleHook(IArchitectureLifecycleHook hook) diff --git a/GFramework.Core.Tests/Coroutine/CommandCoroutineExtensionsTests.cs b/GFramework.Core.Tests/Coroutine/CommandCoroutineExtensionsTests.cs index c6b100b4..494688bd 100644 --- a/GFramework.Core.Tests/Coroutine/CommandCoroutineExtensionsTests.cs +++ b/GFramework.Core.Tests/Coroutine/CommandCoroutineExtensionsTests.cs @@ -6,6 +6,7 @@ using GFramework.Core.Abstractions.Rule; using GFramework.Core.Coroutine.Extensions; using GFramework.Core.Coroutine.Instructions; using Moq; +using NUnit.Framework; namespace GFramework.Core.Tests.Coroutine; @@ -18,6 +19,8 @@ namespace GFramework.Core.Tests.Coroutine; [TestFixture] public class CommandCoroutineExtensionsTests { + private static readonly TimeSpan WaitForTaskTimeout = TimeSpan.FromSeconds(1); + /// /// 测试用的简单命令类 /// @@ -83,15 +86,10 @@ public class CommandCoroutineExtensionsTests var coroutine = contextAware.SendCommandCoroutineWithErrorHandler(command, ex => capturedException = ex); - // 迭代协程直到完成 - while (coroutine.MoveNext()) - { - if (coroutine.Current is WaitForTask waitForTask) - { - // 等待任务完成 - await Task.Delay(10); - } - } + Assert.That(coroutine.MoveNext(), Is.True); + Assert.That(coroutine.Current, Is.TypeOf()); + await WaitForTaskAsync((WaitForTask)coroutine.Current); + Assert.That(coroutine.MoveNext(), Is.False); Assert.That(capturedException, Is.Null); } @@ -114,15 +112,10 @@ public class CommandCoroutineExtensionsTests var coroutine = contextAware.SendCommandCoroutineWithErrorHandler(command, ex => capturedException = ex); - // 迭代协程直到完成 - while (coroutine.MoveNext()) - { - if (coroutine.Current is WaitForTask waitForTask) - { - // 等待任务完成 - await Task.Delay(10); - } - } + Assert.That(coroutine.MoveNext(), Is.True); + Assert.That(coroutine.Current, Is.TypeOf()); + await WaitForTaskAsync((WaitForTask)coroutine.Current); + Assert.That(coroutine.MoveNext(), Is.False); Assert.That(capturedException, Is.Not.Null); // 异常被包装为 AggregateException @@ -148,17 +141,12 @@ public class CommandCoroutineExtensionsTests var coroutine = contextAware.SendCommandCoroutineWithErrorHandler(command); - // 迭代协程应该抛出异常 - Assert.Throws(() => - { - while (coroutine.MoveNext()) - { - if (coroutine.Current is WaitForTask waitForTask) - { - Task.Delay(10).Wait(); - } - } - }); + Assert.That(coroutine.MoveNext(), Is.True); + Assert.That(coroutine.Current, Is.TypeOf()); + Assert.That( + SpinWait.SpinUntil(() => ((WaitForTask)coroutine.Current).IsDone, WaitForTaskTimeout), + Is.True); + Assert.Throws(() => coroutine.MoveNext()); } /// @@ -201,8 +189,9 @@ public class CommandCoroutineExtensionsTests }); // 启动协程并等待命令执行完成 - coroutine.MoveNext(); // 进入命令发送阶段 - if (coroutine.Current is WaitForTask waitForTask) await Task.Delay(10); // 等待命令任务完成 + Assert.That(coroutine.MoveNext(), Is.True); // 进入命令发送阶段 + Assert.That(coroutine.Current, Is.TypeOf()); + await WaitForTaskAsync((WaitForTask)coroutine.Current); // 此时协程应该在等待事件 Assert.That(coroutine.MoveNext(), Is.True); // 等待事件阶段 @@ -296,15 +285,16 @@ public class CommandCoroutineExtensionsTests command); // null回调 // 启动协程 - coroutine.MoveNext(); // 进入命令发送阶段 - if (coroutine.Current is WaitForTask waitForTask) await Task.Delay(10); // 等待命令任务完成 + Assert.That(coroutine.MoveNext(), Is.True); // 进入命令发送阶段 + Assert.That(coroutine.Current, Is.TypeOf()); + await WaitForTaskAsync((WaitForTask)coroutine.Current); // 触发事件 var testEvent = new TestEvent { Data = "TestData" }; eventCallback?.Invoke(testEvent); // 协程应该能正常完成 - Assert.That(() => coroutine.MoveNext(), Throws.Nothing); + Assert.DoesNotThrow(() => coroutine.MoveNext()); } /// @@ -340,8 +330,9 @@ public class CommandCoroutineExtensionsTests _ => { }); // 启动协程 - 命令失败时协程仍然继续 - coroutine.MoveNext(); // 进入命令发送阶段 - if (coroutine.Current is WaitForTask waitForTask) await Task.Delay(10); // 等待命令任务完成 + Assert.That(coroutine.MoveNext(), Is.True); // 进入命令发送阶段 + Assert.That(coroutine.Current, Is.TypeOf()); + await WaitForTaskAsync((WaitForTask)coroutine.Current); // 命令执行失败后,协程继续执行 Assert.Pass(); @@ -441,4 +432,18 @@ public class CommandCoroutineExtensionsTests // 调用 MoveNext 时应该抛出 InvalidOperationException Assert.Throws(() => coroutine.MoveNext()); } -} \ No newline at end of file + + private static async Task WaitForTaskAsync(WaitForTask waitForTask) + { + var timeoutAt = DateTime.UtcNow + WaitForTaskTimeout; + + // 协程通过轮询 IsDone 观察异步命令完成,这里保持相同语义但避免固定延时。 + while (!waitForTask.IsDone) + { + if (DateTime.UtcNow >= timeoutAt) + Assert.Fail("WaitForTask did not complete within the expected time."); + + await Task.Yield(); + } + } +} diff --git a/GFramework.Core.Tests/Coroutine/TaskCoroutineExtensionsTests.cs b/GFramework.Core.Tests/Coroutine/TaskCoroutineExtensionsTests.cs index 946ba9a4..012fa13e 100644 --- a/GFramework.Core.Tests/Coroutine/TaskCoroutineExtensionsTests.cs +++ b/GFramework.Core.Tests/Coroutine/TaskCoroutineExtensionsTests.cs @@ -66,7 +66,7 @@ public class TaskCoroutineExtensionsTests var task = Task.FromResult(42); var instruction = task.AsCoroutineInstruction(); - task.Wait(); + task.ConfigureAwait(false).GetAwaiter().GetResult(); Assert.That(instruction.Result, Is.EqualTo(42)); } @@ -165,7 +165,7 @@ public class TaskCoroutineExtensionsTests Assert.That(completed, Is.False); tcs.SetResult(null); - Task.Delay(50).Wait(); + Task.Delay(50).ConfigureAwait(false).GetAwaiter().GetResult(); scheduler.Update(); scheduler.Update(); @@ -189,7 +189,7 @@ public class TaskCoroutineExtensionsTests Assert.That(scheduler.ActiveCoroutineCount, Is.EqualTo(1)); tcs.SetResult(42); - Task.Delay(50).Wait(); + Task.Delay(50).ConfigureAwait(false).GetAwaiter().GetResult(); scheduler.Update(); scheduler.Update(); @@ -265,7 +265,7 @@ public class TaskCoroutineExtensionsTests tcs.SetResult(null); tcs2.SetResult(42); - Task.Delay(50).Wait(); + Task.Delay(50).ConfigureAwait(false).GetAwaiter().GetResult(); scheduler.Update(); scheduler.Update(); @@ -286,4 +286,4 @@ public class TaskCoroutineExtensionsTests CurrentTime += DeltaTime; } } -} \ No newline at end of file +} diff --git a/GFramework.Core.Tests/Coroutine/WaitForTaskTTests.cs b/GFramework.Core.Tests/Coroutine/WaitForTaskTTests.cs index b04ef283..1e3fc8f4 100644 --- a/GFramework.Core.Tests/Coroutine/WaitForTaskTTests.cs +++ b/GFramework.Core.Tests/Coroutine/WaitForTaskTTests.cs @@ -14,7 +14,7 @@ namespace GFramework.Core.Tests.Coroutine } [Test] - public async Task Constructor_WithCompletedTask_IsDoneImmediately() + public void Constructor_WithCompletedTask_IsDoneImmediately() { // Arrange var completedTask = Task.FromResult("test"); @@ -28,7 +28,7 @@ namespace GFramework.Core.Tests.Coroutine } [Test] - public async Task Constructor_WithIncompleteTask_IsNotDoneInitially() + public void Constructor_WithIncompleteTask_IsNotDoneInitially() { // Arrange var tcs = new TaskCompletionSource(); @@ -54,7 +54,7 @@ namespace GFramework.Core.Tests.Coroutine // Act tcs.SetResult("completed"); - await Task.Delay(10); // Allow time for continuation + await Task.Delay(10).ConfigureAwait(false); // Allow time for continuation // Assert final state Assert.That(waitForTask.IsDone, Is.True); @@ -62,7 +62,7 @@ namespace GFramework.Core.Tests.Coroutine } [Test] - public async Task Update_DoesNotChangeState() + public void Update_DoesNotChangeState() { // Arrange var completedTask = Task.FromResult("test"); @@ -85,7 +85,7 @@ namespace GFramework.Core.Tests.Coroutine // Act tcs.SetException(new InvalidOperationException("Test exception")); - await Task.Delay(10); // Allow time for continuation + await Task.Delay(10).ConfigureAwait(false); // Allow time for continuation // Assert Assert.That(waitForTask.IsDone, Is.True); @@ -93,4 +93,4 @@ namespace GFramework.Core.Tests.Coroutine Assert.That(waitForTask.Exception?.InnerException, Is.TypeOf()); } } -} \ No newline at end of file +} diff --git a/GFramework.Core.Tests/Extensions/AsyncExtensionsTests.cs b/GFramework.Core.Tests/Extensions/AsyncExtensionsTests.cs index 82d50b7d..ed678431 100644 --- a/GFramework.Core.Tests/Extensions/AsyncExtensionsTests.cs +++ b/GFramework.Core.Tests/Extensions/AsyncExtensionsTests.cs @@ -33,11 +33,11 @@ public class AsyncExtensionsTests public void WithTimeout_Should_Throw_TimeoutException_When_Task_Exceeds_Timeout() { // Act & Assert - Assert.ThrowsAsync(async () => - await AsyncExtensions.WithTimeoutAsync( + Assert.ThrowsAsync(() => + AsyncExtensions.WithTimeoutAsync( async ct => { - await Task.Delay(TimeSpan.FromSeconds(2), ct); + await Task.Delay(TimeSpan.FromSeconds(2), ct).ConfigureAwait(false); return 42; }, TimeSpan.FromMilliseconds(100))); @@ -53,11 +53,11 @@ public class AsyncExtensionsTests using var cts = new CancellationTokenSource(); cts.Cancel(); // Act & Assert - Assert.ThrowsAsync(async () => - await AsyncExtensions.WithTimeoutAsync( + Assert.ThrowsAsync(() => + AsyncExtensions.WithTimeoutAsync( async ct => { - await Task.Delay(TimeSpan.FromSeconds(2), ct); + await Task.Delay(TimeSpan.FromSeconds(2), ct).ConfigureAwait(false); return 42; }, TimeSpan.FromSeconds(1), @@ -74,13 +74,13 @@ public class AsyncExtensionsTests var innerTaskCanceled = false; // Act & Assert - Assert.ThrowsAsync(async () => - await AsyncExtensions.WithTimeoutAsync( + Assert.ThrowsAsync(() => + AsyncExtensions.WithTimeoutAsync( async ct => { try { - await Task.Delay(TimeSpan.FromSeconds(5), ct); + await Task.Delay(TimeSpan.FromSeconds(5), ct).ConfigureAwait(false); return 0; } catch (OperationCanceledException) @@ -121,9 +121,9 @@ public class AsyncExtensionsTests public void WithTimeout_NoResult_Should_Throw_TimeoutException_When_Task_Exceeds_Timeout() { // Act & Assert - Assert.ThrowsAsync(async () => - await AsyncExtensions.WithTimeoutAsync( - ct => Task.Delay(TimeSpan.FromSeconds(2), ct), + Assert.ThrowsAsync(() => + AsyncExtensions.WithTimeoutAsync( + ct => Task.Delay(TimeSpan.FromSeconds(2), ct).ConfigureAwait(false), TimeSpan.FromMilliseconds(100))); } @@ -137,13 +137,13 @@ public class AsyncExtensionsTests var innerTaskCanceled = false; // Act & Assert - Assert.ThrowsAsync(async () => - await AsyncExtensions.WithTimeoutAsync( + Assert.ThrowsAsync(() => + AsyncExtensions.WithTimeoutAsync( async ct => { try { - await Task.Delay(TimeSpan.FromSeconds(5), ct); + await Task.Delay(TimeSpan.FromSeconds(5), ct).ConfigureAwait(false); } catch (OperationCanceledException) { @@ -217,8 +217,8 @@ public class AsyncExtensionsTests }; // Act & Assert - Assert.ThrowsAsync(async () => - await taskFactory.WithRetryAsync(2, TimeSpan.FromMilliseconds(10))); + Assert.ThrowsAsync(() => + taskFactory.WithRetryAsync(2, TimeSpan.FromMilliseconds(10))); } /// diff --git a/GFramework.Core.Tests/Functional/ResultTTests.cs b/GFramework.Core.Tests/Functional/ResultTTests.cs index 93dacc5e..993a3e57 100644 --- a/GFramework.Core.Tests/Functional/ResultTTests.cs +++ b/GFramework.Core.Tests/Functional/ResultTTests.cs @@ -414,9 +414,9 @@ public class ResultTTests var result = Result.Succeed(42); var mapped = await result.MapAsync(async x => { - await Task.Delay(1); + await Task.Delay(1).ConfigureAwait(false); return x.ToString(CultureInfo.InvariantCulture); - }); + }).ConfigureAwait(false); Assert.That(mapped.IsSuccess, Is.True); Assert.That(mapped.Match(succ: v => v, fail: _ => ""), Is.EqualTo("42")); } @@ -431,9 +431,9 @@ public class ResultTTests var result = Result.Fail(exception); var mapped = await result.MapAsync(async x => { - await Task.Delay(1); + await Task.Delay(1).ConfigureAwait(false); return x.ToString(CultureInfo.InvariantCulture); - }); + }).ConfigureAwait(false); Assert.That(mapped.IsFaulted, Is.True); Assert.That(mapped.Exception, Is.SameAs(exception)); } @@ -447,9 +447,9 @@ public class ResultTTests var result = Result.Succeed(42); var mapped = await result.MapAsync(async _ => { - await Task.Delay(1); + await Task.Delay(1).ConfigureAwait(false); throw new InvalidOperationException("Async error"); - }); + }).ConfigureAwait(false); Assert.That(mapped.IsFaulted, Is.True); Assert.That(mapped.Exception, Is.TypeOf()); } @@ -551,7 +551,7 @@ public class ResultTTests public void Equals_Should_Return_False_When_Exception_Types_Differ() { var result1 = Result.Fail(new InvalidOperationException("Error")); - var result2 = Result.Fail(new ArgumentException("Error")); + var result2 = Result.Fail(new InvalidCastException("Error")); Assert.That(result1.Equals(result2), Is.False); } diff --git a/GFramework.Core.Tests/Logging/LogContextTests.cs b/GFramework.Core.Tests/Logging/LogContextTests.cs index 63b6c2e4..cdd1f731 100644 --- a/GFramework.Core.Tests/Logging/LogContextTests.cs +++ b/GFramework.Core.Tests/Logging/LogContextTests.cs @@ -152,22 +152,22 @@ public class LogContextTests var task1Values = new List(); var task2Values = new List(); - var task1 = Task.Run(() => + var task1 = Task.Run(async () => { using (LogContext.Push("TaskId", "Task1")) { task1Values.Add(LogContext.Current["TaskId"]); - Task.Delay(50).Wait(); + await Task.Delay(50); task1Values.Add(LogContext.Current["TaskId"]); } }); - var task2 = Task.Run(() => + var task2 = Task.Run(async () => { using (LogContext.Push("TaskId", "Task2")) { task2Values.Add(LogContext.Current["TaskId"]); - Task.Delay(50).Wait(); + await Task.Delay(50); task2Values.Add(LogContext.Current["TaskId"]); } }); @@ -201,4 +201,4 @@ public class LogContextTests Assert.That(LogContext.Current.Count, Is.EqualTo(0)); } -} \ No newline at end of file +} diff --git a/GFramework.Core.Tests/Pause/PauseStackManagerTests.cs b/GFramework.Core.Tests/Pause/PauseStackManagerTests.cs index 6e7b0581..8ad83233 100644 --- a/GFramework.Core.Tests/Pause/PauseStackManagerTests.cs +++ b/GFramework.Core.Tests/Pause/PauseStackManagerTests.cs @@ -22,9 +22,9 @@ public class PauseStackManagerTests /// 在每个测试方法执行后清理资源 /// [TearDown] - public void TearDown() + public async Task TearDown() { - _manager.DestroyAsync(); + await _manager.DestroyAsync().ConfigureAwait(false); } private PauseStackManager _manager = null!; @@ -416,7 +416,7 @@ public class PauseStackManagerTests _manager.Push("Gameplay", PauseGroup.Gameplay); mockHandler.Reset(); - await _manager.DestroyAsync(); + await _manager.DestroyAsync().ConfigureAwait(false); Assert.That(mockHandler.CallCount, Is.EqualTo(2)); Assert.That(mockHandler.LastIsPaused, Is.False); diff --git a/GFramework.Core/Extensions/AsyncExtensions.cs b/GFramework.Core/Extensions/AsyncExtensions.cs index 47124086..246252ca 100644 --- a/GFramework.Core/Extensions/AsyncExtensions.cs +++ b/GFramework.Core/Extensions/AsyncExtensions.cs @@ -28,7 +28,10 @@ public static class AsyncExtensions TimeSpan timeout, CancellationToken cancellationToken = default) { - ArgumentNullException.ThrowIfNull(taskFactory); + if (taskFactory is null) + { + throw new ArgumentNullException(nameof(taskFactory)); + } // linkedCts 同时响应:超时 + 外部取消 using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); @@ -71,7 +74,10 @@ public static class AsyncExtensions TimeSpan timeout, CancellationToken cancellationToken = default) { - ArgumentNullException.ThrowIfNull(taskFactory); + if (taskFactory is null) + { + throw new ArgumentNullException(nameof(taskFactory)); + } using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); linkedCts.CancelAfter(timeout); @@ -113,8 +119,15 @@ public static class AsyncExtensions /// public static async Task WithFallbackAsync(this Task task, Func fallback) { - ArgumentNullException.ThrowIfNull(task); - ArgumentNullException.ThrowIfNull(fallback); + if (task is null) + { + throw new ArgumentNullException(nameof(task)); + } + + if (fallback is null) + { + throw new ArgumentNullException(nameof(fallback)); + } try { diff --git a/GFramework.Core/Extensions/CollectionExtensions.cs b/GFramework.Core/Extensions/CollectionExtensions.cs index 8a57ce46..baa2c4d4 100644 --- a/GFramework.Core/Extensions/CollectionExtensions.cs +++ b/GFramework.Core/Extensions/CollectionExtensions.cs @@ -20,8 +20,15 @@ public static class CollectionExtensions /// public static void ForEach(this IEnumerable source, Action action) { - ArgumentNullException.ThrowIfNull(source); - ArgumentNullException.ThrowIfNull(action); + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (action is null) + { + throw new ArgumentNullException(nameof(action)); + } foreach (var item in source) action(item); } @@ -58,7 +65,10 @@ public static class CollectionExtensions /// public static IEnumerable WhereNotNull(this IEnumerable source) where T : class { - ArgumentNullException.ThrowIfNull(source); + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } return source.Where(item => item is not null)!; } @@ -88,9 +98,20 @@ public static class CollectionExtensions Func valueSelector) where TKey : notnull #pragma warning restore MA0016 { - ArgumentNullException.ThrowIfNull(source); - ArgumentNullException.ThrowIfNull(keySelector); - ArgumentNullException.ThrowIfNull(valueSelector); + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (keySelector is null) + { + throw new ArgumentNullException(nameof(keySelector)); + } + + if (valueSelector is null) + { + throw new ArgumentNullException(nameof(valueSelector)); + } var dictionary = new Dictionary(); diff --git a/GFramework.Core/Extensions/ContextAwareCommandExtensions.cs b/GFramework.Core/Extensions/ContextAwareCommandExtensions.cs index 49676e56..5a98d179 100644 --- a/GFramework.Core/Extensions/ContextAwareCommandExtensions.cs +++ b/GFramework.Core/Extensions/ContextAwareCommandExtensions.cs @@ -19,8 +19,15 @@ public static class ContextAwareCommandExtensions public static TResult SendCommand(this IContextAware contextAware, ICommand command) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (command is null) + { + throw new ArgumentNullException(nameof(command)); + } var context = contextAware.GetContext(); return context.SendCommand(command); @@ -34,8 +41,15 @@ public static class ContextAwareCommandExtensions /// 当 contextAware 或 command 为 null 时抛出 public static void SendCommand(this IContextAware contextAware, ICommand command) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (command is null) + { + throw new ArgumentNullException(nameof(command)); + } var context = contextAware.GetContext(); context.SendCommand(command); @@ -50,8 +64,15 @@ public static class ContextAwareCommandExtensions /// 当 contextAware 或 command 为 null 时抛出 public static async Task SendCommandAsync(this IContextAware contextAware, IAsyncCommand command) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (command is null) + { + throw new ArgumentNullException(nameof(command)); + } var context = contextAware.GetContext(); await context.SendCommandAsync(command).ConfigureAwait(false); @@ -68,8 +89,15 @@ public static class ContextAwareCommandExtensions public static async Task SendCommandAsync(this IContextAware contextAware, IAsyncCommand command) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(command); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (command is null) + { + throw new ArgumentNullException(nameof(command)); + } var context = contextAware.GetContext(); return await context.SendCommandAsync(command).ConfigureAwait(false); diff --git a/GFramework.Core/Extensions/ContextAwareEnvironmentExtensions.cs b/GFramework.Core/Extensions/ContextAwareEnvironmentExtensions.cs index 48abcfeb..5fd7766a 100644 --- a/GFramework.Core/Extensions/ContextAwareEnvironmentExtensions.cs +++ b/GFramework.Core/Extensions/ContextAwareEnvironmentExtensions.cs @@ -16,7 +16,11 @@ public static class ContextAwareEnvironmentExtensions /// 指定类型的环境对象,如果无法转换则返回null public static T? GetEnvironment(this IContextAware contextAware) where T : class { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetEnvironment() as T; } @@ -28,8 +32,12 @@ public static class ContextAwareEnvironmentExtensions /// 环境对象 public static IEnvironment GetEnvironment(this IContextAware contextAware) { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetEnvironment(); } -} \ No newline at end of file +} diff --git a/GFramework.Core/Extensions/ContextAwareEventExtensions.cs b/GFramework.Core/Extensions/ContextAwareEventExtensions.cs index 34512eeb..f1e35732 100644 --- a/GFramework.Core/Extensions/ContextAwareEventExtensions.cs +++ b/GFramework.Core/Extensions/ContextAwareEventExtensions.cs @@ -16,7 +16,11 @@ public static class ContextAwareEventExtensions /// 当 contextAware 为 null 时抛出 public static void SendEvent(this IContextAware contextAware) where TEvent : new() { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); context.SendEvent(); } @@ -30,8 +34,15 @@ public static class ContextAwareEventExtensions /// 当 contextAware 或 e 为 null 时抛出 public static void SendEvent(this IContextAware contextAware, TEvent e) where TEvent : class { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(e); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (e is null) + { + throw new ArgumentNullException(nameof(e)); + } var context = contextAware.GetContext(); context.SendEvent(e); @@ -46,8 +57,15 @@ public static class ContextAwareEventExtensions /// 事件注销接口 public static IUnRegister RegisterEvent(this IContextAware contextAware, Action handler) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(handler); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (handler is null) + { + throw new ArgumentNullException(nameof(handler)); + } var context = contextAware.GetContext(); return context.RegisterEvent(handler); @@ -61,10 +79,17 @@ public static class ContextAwareEventExtensions /// 之前绑定的事件处理器 public static void UnRegisterEvent(this IContextAware contextAware, Action onEvent) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(onEvent); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (onEvent is null) + { + throw new ArgumentNullException(nameof(onEvent)); + } var context = contextAware.GetContext(); context.UnRegisterEvent(onEvent); } -} \ No newline at end of file +} diff --git a/GFramework.Core/Extensions/ContextAwareQueryExtensions.cs b/GFramework.Core/Extensions/ContextAwareQueryExtensions.cs index 63ad260c..07e6aa7a 100644 --- a/GFramework.Core/Extensions/ContextAwareQueryExtensions.cs +++ b/GFramework.Core/Extensions/ContextAwareQueryExtensions.cs @@ -18,8 +18,15 @@ public static class ContextAwareQueryExtensions /// 当 contextAware 或 query 为 null 时抛出 public static TResult SendQuery(this IContextAware contextAware, IQuery query) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(query); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (query is null) + { + throw new ArgumentNullException(nameof(query)); + } var context = contextAware.GetContext(); return context.SendQuery(query); @@ -37,8 +44,15 @@ public static class ContextAwareQueryExtensions public static async Task SendQueryAsync(this IContextAware contextAware, IAsyncQuery query) { - ArgumentNullException.ThrowIfNull(contextAware); - ArgumentNullException.ThrowIfNull(query); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + + if (query is null) + { + throw new ArgumentNullException(nameof(query)); + } var context = contextAware.GetContext(); return await context.SendQueryAsync(query).ConfigureAwait(false); diff --git a/GFramework.Core/Extensions/ContextAwareServiceExtensions.cs b/GFramework.Core/Extensions/ContextAwareServiceExtensions.cs index 2b0b8ecf..ae88a4af 100644 --- a/GFramework.Core/Extensions/ContextAwareServiceExtensions.cs +++ b/GFramework.Core/Extensions/ContextAwareServiceExtensions.cs @@ -24,7 +24,11 @@ public static class ContextAwareServiceExtensions /// 当指定服务未注册时抛出 public static TService GetService(this IContextAware contextAware) where TService : class { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return GetRequiredComponent(context, static architectureContext => architectureContext.GetService(), "Service"); @@ -40,7 +44,11 @@ public static class ContextAwareServiceExtensions /// 当指定系统未注册时抛出 public static TSystem GetSystem(this IContextAware contextAware) where TSystem : class, ISystem { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return GetRequiredComponent(context, static architectureContext => architectureContext.GetSystem(), "System"); @@ -56,7 +64,11 @@ public static class ContextAwareServiceExtensions /// 当指定模型未注册时抛出 public static TModel GetModel(this IContextAware contextAware) where TModel : class, IModel { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return GetRequiredComponent(context, static architectureContext => architectureContext.GetModel(), "Model"); @@ -72,7 +84,11 @@ public static class ContextAwareServiceExtensions /// 当指定工具未注册时抛出 public static TUtility GetUtility(this IContextAware contextAware) where TUtility : class, IUtility { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return GetRequiredComponent(context, static architectureContext => architectureContext.GetUtility(), "Utility"); @@ -92,7 +108,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetServices(this IContextAware contextAware) where TService : class { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetServices(); } @@ -107,7 +127,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetSystems(this IContextAware contextAware) where TSystem : class, ISystem { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetSystems(); } @@ -122,7 +146,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetModels(this IContextAware contextAware) where TModel : class, IModel { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetModels(); } @@ -137,7 +165,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetUtilities(this IContextAware contextAware) where TUtility : class, IUtility { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetUtilities(); } @@ -152,7 +184,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetServicesByPriority(this IContextAware contextAware) where TService : class { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetServicesByPriority(); } @@ -167,7 +203,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetSystemsByPriority(this IContextAware contextAware) where TSystem : class, ISystem { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetSystemsByPriority(); } @@ -182,7 +222,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetModelsByPriority(this IContextAware contextAware) where TModel : class, IModel { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetModelsByPriority(); } @@ -197,7 +241,11 @@ public static class ContextAwareServiceExtensions public static IReadOnlyList GetUtilitiesByPriority(this IContextAware contextAware) where TUtility : class, IUtility { - ArgumentNullException.ThrowIfNull(contextAware); + if (contextAware is null) + { + throw new ArgumentNullException(nameof(contextAware)); + } + var context = contextAware.GetContext(); return context.GetUtilitiesByPriority(); } @@ -206,11 +254,14 @@ public static class ContextAwareServiceExtensions Func resolver, string componentKind) where TComponent : class { - ArgumentNullException.ThrowIfNull(context); + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } var component = resolver(context); return component ?? throw new InvalidOperationException($"{componentKind} {typeof(TComponent)} not registered"); } #endregion -} \ No newline at end of file +} diff --git a/GFramework.Core/Extensions/GuardExtensions.cs b/GFramework.Core/Extensions/GuardExtensions.cs index de68dcdf..716a3127 100644 --- a/GFramework.Core/Extensions/GuardExtensions.cs +++ b/GFramework.Core/Extensions/GuardExtensions.cs @@ -27,7 +27,9 @@ public static class GuardExtensions this T? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) where T : class { - ArgumentNullException.ThrowIfNull(value, paramName); + if (value is null) + throw new ArgumentNullException(paramName); + return value; } @@ -51,7 +53,8 @@ public static class GuardExtensions this string? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) { - ArgumentNullException.ThrowIfNull(value, paramName); + if (value is null) + throw new ArgumentNullException(paramName); if (value.Length == 0) throw new ArgumentException("字符串不能为空", paramName); @@ -79,7 +82,8 @@ public static class GuardExtensions this string? value, [CallerArgumentExpression(nameof(value))] string? paramName = null) { - ArgumentNullException.ThrowIfNull(value, paramName); + if (value is null) + throw new ArgumentNullException(paramName); if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException("字符串不能为空或仅包含空白字符", paramName); @@ -108,7 +112,8 @@ public static class GuardExtensions this IEnumerable? source, [CallerArgumentExpression(nameof(source))] string? paramName = null) { - ArgumentNullException.ThrowIfNull(source, paramName); + if (source is null) + throw new ArgumentNullException(paramName); if (!source.Any()) throw new ArgumentException("集合不能为空", paramName); diff --git a/GFramework.Core/Extensions/NumericExtensions.cs b/GFramework.Core/Extensions/NumericExtensions.cs index 31e0b471..f27503b1 100644 --- a/GFramework.Core/Extensions/NumericExtensions.cs +++ b/GFramework.Core/Extensions/NumericExtensions.cs @@ -25,9 +25,14 @@ public static class NumericExtensions /// public static bool Between(this T value, T min, T max, bool inclusive = true) where T : IComparable { - ArgumentNullException.ThrowIfNull(value); - ArgumentNullException.ThrowIfNull(min); - ArgumentNullException.ThrowIfNull(max); + if (value is null) + throw new ArgumentNullException(nameof(value)); + + if (min is null) + throw new ArgumentNullException(nameof(min)); + + if (max is null) + throw new ArgumentNullException(nameof(max)); if (min.CompareTo(max) > 0) throw new ArgumentException($"最小值 ({min}) 不能大于最大值 ({max})", nameof(min)); diff --git a/GFramework.Core/Extensions/StoreEventBusExtensions.cs b/GFramework.Core/Extensions/StoreEventBusExtensions.cs index df3ad0ea..5d09ae24 100644 --- a/GFramework.Core/Extensions/StoreEventBusExtensions.cs +++ b/GFramework.Core/Extensions/StoreEventBusExtensions.cs @@ -27,8 +27,15 @@ public static class StoreEventBusExtensions bool publishDispatches = true, bool publishStateChanges = true) { - ArgumentNullException.ThrowIfNull(store); - ArgumentNullException.ThrowIfNull(eventBus); + if (store is null) + { + throw new ArgumentNullException(nameof(store)); + } + + if (eventBus is null) + { + throw new ArgumentNullException(nameof(eventBus)); + } IUnRegister? dispatchBridge = null; IUnRegister? stateBridge = null; @@ -60,8 +67,15 @@ public static class StoreEventBusExtensions /// 用于移除 dispatch 桥接中间件的句柄。 public static IUnRegister BridgeDispatchesToEventBus(this Store store, IEventBus eventBus) { - ArgumentNullException.ThrowIfNull(store); - ArgumentNullException.ThrowIfNull(eventBus); + if (store is null) + { + throw new ArgumentNullException(nameof(store)); + } + + if (eventBus is null) + { + throw new ArgumentNullException(nameof(eventBus)); + } return store.RegisterMiddleware(new DispatchEventBusMiddleware(eventBus)); } @@ -77,8 +91,15 @@ public static class StoreEventBusExtensions public static IUnRegister BridgeStateChangesToEventBus(this IReadonlyStore store, IEventBus eventBus) { - ArgumentNullException.ThrowIfNull(store); - ArgumentNullException.ThrowIfNull(eventBus); + if (store is null) + { + throw new ArgumentNullException(nameof(store)); + } + + if (eventBus is null) + { + throw new ArgumentNullException(nameof(eventBus)); + } return store.Subscribe(state => eventBus.Send(new StoreStateChangedEvent(state, DateTimeOffset.UtcNow))); @@ -115,4 +136,4 @@ public static class StoreEventBusExtensions _eventBus.Send(new StoreDispatchedEvent(dispatchRecord)); } } -} \ No newline at end of file +} diff --git a/GFramework.Core/Extensions/StringExtensions.cs b/GFramework.Core/Extensions/StringExtensions.cs index 63ecc4e9..f2403aec 100644 --- a/GFramework.Core/Extensions/StringExtensions.cs +++ b/GFramework.Core/Extensions/StringExtensions.cs @@ -38,8 +38,11 @@ public static class StringExtensions /// public static string Truncate(this string str, int maxLength, string suffix = "...") { - ArgumentNullException.ThrowIfNull(str); - ArgumentNullException.ThrowIfNull(suffix); + if (str is null) + throw new ArgumentNullException(nameof(str)); + + if (suffix is null) + throw new ArgumentNullException(nameof(suffix)); if (maxLength < suffix.Length) throw new ArgumentOutOfRangeException(nameof(maxLength), @@ -66,9 +69,12 @@ public static class StringExtensions /// public static string Join(this IEnumerable values, string separator) { - ArgumentNullException.ThrowIfNull(values); - ArgumentNullException.ThrowIfNull(separator); + if (values is null) + throw new ArgumentNullException(nameof(values)); + + if (separator is null) + throw new ArgumentNullException(nameof(separator)); return string.Join(separator, values); } -} \ No newline at end of file +} diff --git a/GFramework.Core/StateManagement/StoreBuilder.cs b/GFramework.Core/StateManagement/StoreBuilder.cs index 48802aaa..fca6bc34 100644 --- a/GFramework.Core/StateManagement/StoreBuilder.cs +++ b/GFramework.Core/StateManagement/StoreBuilder.cs @@ -39,7 +39,9 @@ public sealed class StoreBuilder : IStoreBuilder /// 当前构建器实例。 public IStoreBuilder UseMiddleware(IStoreMiddleware middleware) { - ArgumentNullException.ThrowIfNull(middleware); + if (middleware is null) + throw new ArgumentNullException(nameof(middleware)); + _configurators.Add(store => store.UseMiddleware(middleware)); return this; } @@ -108,7 +110,9 @@ public sealed class StoreBuilder : IStoreBuilder /// 当前构建器实例。 public IStoreBuilder AddReducer(Func reducer) { - ArgumentNullException.ThrowIfNull(reducer); + if (reducer is null) + throw new ArgumentNullException(nameof(reducer)); + _configurators.Add(store => store.RegisterReducer(reducer)); return this; } @@ -121,8 +125,10 @@ public sealed class StoreBuilder : IStoreBuilder /// 当前构建器实例。 public IStoreBuilder AddReducer(IReducer reducer) { - ArgumentNullException.ThrowIfNull(reducer); + if (reducer is null) + throw new ArgumentNullException(nameof(reducer)); + _configurators.Add(store => store.RegisterReducer(reducer)); return this; } -} \ No newline at end of file +} diff --git a/GFramework.Core/StateManagement/StoreSelection.cs b/GFramework.Core/StateManagement/StoreSelection.cs index b912da46..9f0bbe6f 100644 --- a/GFramework.Core/StateManagement/StoreSelection.cs +++ b/GFramework.Core/StateManagement/StoreSelection.cs @@ -82,7 +82,9 @@ public sealed class StoreSelection : IReadonlyBindablePropert /// 用于取消订阅的句柄。 IUnRegister IEvent.Register(Action onEvent) { - ArgumentNullException.ThrowIfNull(onEvent); + if (onEvent is null) + throw new ArgumentNullException(nameof(onEvent)); + return Register(_ => onEvent()); } @@ -94,7 +96,8 @@ public sealed class StoreSelection : IReadonlyBindablePropert /// 时抛出。 public IUnRegister Register(Action onValueChanged) { - ArgumentNullException.ThrowIfNull(onValueChanged); + if (onValueChanged is null) + throw new ArgumentNullException(nameof(onValueChanged)); var subscription = new SelectionListenerSubscription(onValueChanged); var shouldAttach = false; @@ -126,7 +129,8 @@ public sealed class StoreSelection : IReadonlyBindablePropert /// 时抛出。 public IUnRegister RegisterWithInitValue(Action action) { - ArgumentNullException.ThrowIfNull(action); + if (action is null) + throw new ArgumentNullException(nameof(action)); var subscription = new SelectionListenerSubscription(action) { @@ -189,7 +193,8 @@ public sealed class StoreSelection : IReadonlyBindablePropert /// 时抛出。 public void UnRegister(Action onValueChanged) { - ArgumentNullException.ThrowIfNull(onValueChanged); + if (onValueChanged is null) + throw new ArgumentNullException(nameof(onValueChanged)); SelectionListenerSubscription? subscriptionToRemove = null; @@ -391,4 +396,4 @@ public sealed class StoreSelection : IReadonlyBindablePropert /// public TSelected PendingValue { get; set; } = default!; } -} \ No newline at end of file +}