From 65bb02285f429b32bf8c4e4cff91a9c6f86c8963 Mon Sep 17 00:00:00 2001 From: Chris Pulman Date: Thu, 7 Dec 2023 18:21:59 +0530 Subject: [PATCH] Strengthen EditorConfig to help enforce coding standards (#775) * Strengthen EditorConfig to help enforce coding standards Update code to match coding standards * Update ObservableSpy.cs Fix release version * Further code fixes after SonarCloud tests * Fix issues picked up by SonarCloud * Update new code * introduce ThrowArgumentNullExceptionIfNull Reduce code bloat by using extension method for ArgumentNullException's. This was chosen due to current target frameworks. If in the future netstandard2.1 + compliant frameworks are used we can switch methods. * Update API checks * Update remaining ArgumentNullException to use extension method * Fix code after merge * Update code after merge * The PR #771 introduced inconsistent results src\DynamicData.Tests\Cache\TransformFixtureParallel.cs line 95 - Test Needs fixing or updated Functionality needs checking * Skip removed to ensure fix is applied before merge Test - src\DynamicData.Tests\Cache\TransformFixtureParallel.cs SameKeyChanges on line 95 needs attention * Fixed intermittent test failures introduced by 6395e7de50e7cc26cdea5e3c50a711ffa4b21851 --------- Co-authored-by: JakenVeina --- .editorconfig | 414 +-- src/Directory.Build.props | 2 +- ...ts.DynamicDataTests.DotNet6_0.verified.txt | 58 +- ...ts.DynamicDataTests.DotNet7_0.verified.txt | 58 +- ...ts.DynamicDataTests.DotNet8_0.verified.txt | 58 +- .../AggregationTests/AggregationFixture.cs | 5 +- .../AggregationTests/AverageFixture.cs | 10 +- .../AggregationTests/MaxFixture.cs | 10 +- .../AggregationTests/MinFixture.cs | 10 +- .../AggregationTests/SumFixture.cs | 10 +- src/DynamicData.Tests/AutoRefreshFilter.cs | 12 +- .../BindingListBindCacheSortedFixture.cs | 2 +- .../Binding/BindingListToChangeSetFixture.cs | 5 +- ...eeplyNestedNotifyPropertyChangedFixture.cs | 47 +- .../IObservableListBindCacheFixture.cs | 2 +- .../IObservableListBindCacheSortedFixture.cs | 13 +- .../Binding/IObservableListBindListFixture.cs | 2 +- ...bleCollectionExtendedToChangeSetFixture.cs | 5 +- .../ObservableCollectionToChangeSetFixture.cs | 10 +- ...yObservableCollectionToChangeSetFixture.cs | 10 +- src/DynamicData.Tests/Cache/AndFixture.cs | 6 +- .../Cache/AutoRefreshFixture.cs | 12 +- .../Cache/BatchIfWithTimeOutFixture.cs | 5 +- .../Cache/DisposeManyFixture.cs | 7 +- .../Cache/EditDiffChangeSetFixture.cs | 12 +- .../Cache/EditDiffChangeSetOptionalFixture.cs | 12 +- .../Cache/EnsureUniqueKeysFixture.cs | 11 +- src/DynamicData.Tests/Cache/ExceptFixture.cs | 6 +- .../Cache/FilterOnObservableFixture.cs | 2 +- .../Cache/FilterOnPropertyFixture.cs | 5 +- .../Cache/ForEachChangeFixture.cs | 10 +- .../Cache/FromAsyncFixture.cs | 5 +- .../Cache/FullJoinFixture.cs | 103 +- .../Cache/FullJoinManyFixture.cs | 1 + src/DynamicData.Tests/Cache/GroupFixture.cs | 54 +- .../Cache/IgnoreUpdateFixture.cs | 1 + .../Cache/IncludeUpdateFixture.cs | 1 + .../Cache/InnerJoinFixture.cs | 101 +- .../Cache/InnerJoinManyFixture.cs | 1 + .../Cache/KeyValueCollectionEx.cs | 5 +- .../Cache/LeftJoinFixture.cs | 95 +- .../Cache/LeftJoinManyFixture.cs | 3 +- .../Cache/MergeChangeSetsFixture.cs | 5 +- .../Cache/MergeManyCacheChangeSetsFixture.cs | 5 +- ...ManyCacheChangeSetsSourceCompareFixture.cs | 5 +- .../Cache/MergeManyFixture.cs | 19 +- .../Cache/MergeManyItemsFixture.cs | 19 +- .../Cache/MergeManyWithKeyOverloadFixture.cs | 29 +- .../Cache/ObservableCachePreviewFixture.cs | 4 +- .../Cache/ObservableChangeSetFixture.cs | 4 +- src/DynamicData.Tests/Cache/OnItemFixture.cs | 8 +- src/DynamicData.Tests/Cache/OrFixture.cs | 6 +- src/DynamicData.Tests/Cache/PageFixture.cs | 10 +- .../Cache/RefCountFixture.cs | 10 +- .../Cache/RightJoinFixture.cs | 101 +- .../Cache/RightJoinManyFixture.cs | 1 + .../Cache/SizeLimitFixture.cs | 4 +- src/DynamicData.Tests/Cache/SortFixture.cs | 124 +- .../Cache/SortObservableFixtureFixture.cs | 1 + .../Cache/SubscribeManyFixture.cs | 19 +- .../Cache/ToObservableOptionalFixture.cs | 34 +- .../Cache/TransformFixture.cs | 15 +- .../Cache/TransformFixtureParallel.cs | 1 + .../Cache/TransformSafeAsyncFixture.cs | 5 +- .../Cache/TransformTreeFixture.cs | 50 +- .../Cache/TransformTreeWithRefreshFixture.cs | 34 +- .../Cache/TransformWithInlineUpdateFixture.cs | 5 +- .../Cache/TrueForAllFixture.cs | 14 +- .../Cache/TrueForAnyFixture.cs | 14 +- src/DynamicData.Tests/Cache/WatchFixture.cs | 14 +- src/DynamicData.Tests/Cache/WatcherFixture.cs | 3 + src/DynamicData.Tests/Cache/XorFixture.cs | 6 +- src/DynamicData.Tests/Domain/Market.cs | 6 +- .../Domain/ParentAndChildren.cs | 24 +- src/DynamicData.Tests/Domain/ParentChild.cs | 12 +- src/DynamicData.Tests/Domain/Person.cs | 37 +- .../Domain/PersonEmployment.cs | 36 +- src/DynamicData.Tests/Domain/PersonObs.cs | 61 +- .../Domain/PersonWithChildren.cs | 5 +- .../Domain/PersonWithEmployment.cs | 22 +- .../Domain/PersonWithFriends.cs | 23 +- .../Domain/PersonWithGender.cs | 11 +- .../Domain/PersonWithRelations.cs | 5 +- .../Domain/SelfObservingPerson.cs | 10 +- .../DynamicData.Tests.csproj | 2 +- .../Issues/OnItemRemovedIssue.cs | 8 +- src/DynamicData.Tests/List/AndFixture.cs | 6 +- .../List/AutoRefreshFixture.cs | 33 +- .../List/ChangeAwareListFixture.cs | 15 +- .../List/CreationFixtures.cs | 3 +- .../List/DisposeManyFixture.cs | 7 +- src/DynamicData.Tests/List/ExceptFixture.cs | 6 +- .../List/FilterOnObservableFixture.cs | 5 +- .../List/FilterOnPropertyFixture.cs | 5 +- .../List/FilterWithObservable.cs | 1 + .../List/ForEachChangeFixture.cs | 10 +- .../List/FromAsyncFixture.cs | 5 +- src/DynamicData.Tests/List/GroupOnFixture.cs | 1 + .../List/MergeManyChangeSetsCacheFixture.cs | 5 +- .../List/MergeManyFixture.cs | 29 +- src/DynamicData.Tests/List/OrFixture.cs | 6 +- src/DynamicData.Tests/List/PageFixture.cs | 13 +- .../List/RecursiveTransformManyFixture.cs | 1 + src/DynamicData.Tests/List/RefCountFixture.cs | 10 +- .../List/RemoveManyFixture.cs | 5 +- .../List/SizeLimitFixture.cs | 4 +- src/DynamicData.Tests/List/SortFixture.cs | 9 +- .../List/SourceListPreviewFixture.cs | 14 +- .../List/SubscribeManyFixture.cs | 19 +- .../List/TransformManyFixture.cs | 17 +- .../List/TransformManyProjectionFixture.cs | 42 +- src/DynamicData.Tests/List/XOrFixture.cs | 6 +- .../Utilities/ComparerExtensions.cs | 6 +- .../Utilities/ObservableSpy.cs | 39 +- .../Utilities/SelectManyExtensions.cs | 30 +- src/DynamicData/Aggregation/AggregateItem.cs | 6 +- src/DynamicData/Aggregation/AggregationEx.cs | 35 +- src/DynamicData/Aggregation/AvgEx.cs | 37 +- src/DynamicData/Aggregation/MaxEx.cs | 36 +- src/DynamicData/Aggregation/StdDevEx.cs | 51 +- src/DynamicData/Aggregation/SumEx.cs | 153 +- src/DynamicData/Alias/ObservableCacheAlias.cs | 156 +- src/DynamicData/Alias/ObservableListAlias.cs | 50 +- src/DynamicData/Binding/BindingListAdaptor.cs | 64 +- .../Binding/BindingListEventsSuspender.cs | 7 +- src/DynamicData/Binding/BindingListEx.cs | 256 +- src/DynamicData/Binding/BindingOptions.cs | 8 +- src/DynamicData/Binding/ExpressionBuilder.cs | 2 +- src/DynamicData/Binding/IObservableListEx.cs | 6 +- .../Binding/NotifyPropertyChangedEx.cs | 221 +- .../Binding/ObservableCollectionAdaptor.cs | 18 +- .../Binding/ObservableCollectionEx.cs | 51 +- .../Binding/ObservableCollectionExtended.cs | 20 +- .../Binding/ObservablePropertyFactoryCache.cs | 15 +- src/DynamicData/Binding/PropertyValue.cs | 2 +- .../Binding/SortedBindingListAdaptor.cs | 36 +- .../SortedObservableCollectionAdaptor.cs | 11 +- src/DynamicData/Cache/Change.cs | 18 +- src/DynamicData/Cache/ChangeAwareCache.cs | 15 +- src/DynamicData/Cache/ChangeSet.cs | 2 +- src/DynamicData/Cache/GroupChangeSet.cs | 2 +- src/DynamicData/Cache/ICache.cs | 2 +- src/DynamicData/Cache/IChangeSetAdaptor.cs | 4 +- .../Cache/ISortedChangeSetAdaptor.cs | 4 +- src/DynamicData/Cache/IndexedItem.cs | 26 +- src/DynamicData/Cache/IntermediateCache.cs | 12 +- .../Cache/Internal/AbstractFilter.cs | 14 +- .../Internal/AnonymousObservableCache.cs | 6 +- src/DynamicData/Cache/Internal/BatchIf.cs | 17 +- src/DynamicData/Cache/Internal/Cache.cs | 5 +- .../Cache/Internal/CacheUpdater.cs | 71 +- .../Cache/Internal/ChangeSetMergeTracker.cs | 6 +- src/DynamicData/Cache/Internal/Combiner.cs | 24 +- .../Cache/Internal/DeferUntilLoaded.cs | 10 +- .../Cache/Internal/DictionaryExtensions.cs | 11 +- src/DynamicData/Cache/Internal/DisposeMany.cs | 7 + .../Cache/Internal/DistinctCalculator.cs | 6 +- .../Cache/Internal/DynamicCombiner.cs | 18 +- .../Cache/Internal/DynamicFilter.cs | 12 +- .../Internal/EditDiffChangeSetOptional.cs | 20 +- .../Cache/Internal/ExpirableItem.cs | 12 +- src/DynamicData/Cache/Internal/FilterEx.cs | 7 +- .../Cache/Internal/FilterOnObservable.cs | 2 +- .../Cache/Internal/FilteredIndexCalculator.cs | 14 +- src/DynamicData/Cache/Internal/FullJoin.cs | 10 +- src/DynamicData/Cache/Internal/GroupOn.cs | 28 +- .../Cache/Internal/GroupOnImmutable.cs | 38 +- .../Cache/Internal/ImmutableGroup.cs | 12 +- .../Cache/Internal/IndexCalculator.cs | 20 +- src/DynamicData/Cache/Internal/InnerJoin.cs | 14 +- .../Cache/Internal/KeyValueComparer.cs | 2 +- src/DynamicData/Cache/Internal/LeftJoin.cs | 6 +- .../Cache/Internal/LockFreeObservableCache.cs | 4 +- .../Cache/Internal/ManagedGroup.cs | 2 +- src/DynamicData/Cache/Internal/MergeMany.cs | 5 +- src/DynamicData/Cache/Internal/Page.cs | 14 +- .../Cache/Internal/ReaderWriter.cs | 31 +- src/DynamicData/Cache/Internal/RightJoin.cs | 8 +- src/DynamicData/Cache/Internal/Sort.cs | 4 +- .../Cache/Internal/StaticFilter.cs | 10 +- .../Cache/Internal/SubscribeMany.cs | 5 +- src/DynamicData/Cache/Internal/TimeExpirer.cs | 2 +- .../Cache/Internal/ToObservableChangeSet.cs | 24 +- .../Cache/Internal/ToObservableOptional.cs | 9 +- .../Cache/Internal/TransformAsync.cs | 10 +- .../Cache/Internal/TransformMany.cs | 3 +- .../Internal/TransformWithForcedTransform.cs | 14 +- .../Internal/TransformWithInlineUpdate.cs | 2 +- src/DynamicData/Cache/Internal/Virtualise.cs | 2 +- src/DynamicData/Cache/Node.cs | 30 +- src/DynamicData/Cache/ObservableCache.cs | 10 +- src/DynamicData/Cache/ObservableCacheEx.cs | 2222 +++++------------ src/DynamicData/Cache/PageRequest.cs | 4 +- src/DynamicData/Cache/PageResponse.cs | 10 +- src/DynamicData/Cache/PagedChangeSet.cs | 2 +- src/DynamicData/Cache/SortedChangeSet.cs | 14 +- src/DynamicData/Cache/SourceCache.cs | 2 +- src/DynamicData/Cache/SourceCacheEx.cs | 10 +- src/DynamicData/Cache/Tests/TestEx.cs | 26 +- src/DynamicData/Cache/VirtualChangeSet.cs | 16 +- src/DynamicData/Cache/VirtualRequest.cs | 4 +- src/DynamicData/Cache/VirtualResponse.cs | 8 +- .../Diagnostics/ChangeStatistics.cs | 17 +- src/DynamicData/Diagnostics/ChangeSummary.cs | 4 +- .../Diagnostics/DiagnosticOperators.cs | 40 +- src/DynamicData/EnumerableEx.cs | 30 +- .../Experimental/ExperimentalEx.cs | 7 +- src/DynamicData/Internal/ExceptionMixins.cs | 17 + src/DynamicData/Kernel/EnumerableEx.cs | 40 +- src/DynamicData/Kernel/EnumeratorIList.cs | 5 +- src/DynamicData/Kernel/Error.cs | 21 +- src/DynamicData/Kernel/InternalEx.cs | 14 +- src/DynamicData/Kernel/ItemWithIndex.cs | 12 +- src/DynamicData/Kernel/ItemWithValue.cs | 12 +- src/DynamicData/Kernel/OptionElse.cs | 12 +- src/DynamicData/Kernel/OptionExtensions.cs | 101 +- .../Kernel/OptionObservableExtensions.cs | 122 +- src/DynamicData/Kernel/Optional.cs | 15 +- src/DynamicData/Kernel/ParallelEx.cs | 12 +- .../Kernel/ReadOnlyCollectionLight.cs | 5 +- src/DynamicData/List/Change.cs | 8 +- src/DynamicData/List/ChangeAwareList.cs | 80 +- src/DynamicData/List/ChangeSet.cs | 6 +- src/DynamicData/List/ChangeSetEx.cs | 52 +- src/DynamicData/List/IChangeSetAdaptor.cs | 4 +- src/DynamicData/List/IExtendedList.cs | 2 +- .../List/Internal/AnonymousObservableList.cs | 6 +- src/DynamicData/List/Internal/AutoRefresh.cs | 7 +- src/DynamicData/List/Internal/BufferIf.cs | 2 +- src/DynamicData/List/Internal/Combiner.cs | 1 + src/DynamicData/List/Internal/DisposeMany.cs | 22 +- src/DynamicData/List/Internal/Distinct.cs | 14 +- .../List/Internal/DynamicCombiner.cs | 6 +- .../List/Internal/ExpirableItem.cs | 14 +- src/DynamicData/List/Internal/Filter.cs | 73 +- .../List/Internal/FilterOnObservable.cs | 24 +- src/DynamicData/List/Internal/FilterStatic.cs | 7 +- src/DynamicData/List/Internal/Group.cs | 14 +- src/DynamicData/List/Internal/GroupOn.cs | 18 +- .../List/Internal/GroupOnImmutable.cs | 22 +- .../List/Internal/ImmutableGroup.cs | 14 +- src/DynamicData/List/Internal/Pager.cs | 20 +- src/DynamicData/List/Internal/ReaderWriter.cs | 26 +- .../List/Internal/ReferenceCountTracker.cs | 17 +- src/DynamicData/List/Internal/Sort.cs | 12 +- .../List/Internal/TransformAsync.cs | 24 +- .../List/Internal/TransformMany.cs | 20 +- src/DynamicData/List/Internal/Transformer.cs | 20 +- .../List/Internal/UnifiedChange.cs | 12 +- src/DynamicData/List/Internal/Virtualiser.cs | 8 +- src/DynamicData/List/ItemChange.cs | 8 +- .../List/Linq/ItemChangeEnumerator.cs | 3 - src/DynamicData/List/ListEx.cs | 200 +- src/DynamicData/List/ObservableListEx.cs | 815 ++---- src/DynamicData/List/SortOptions.cs | 1 - src/DynamicData/List/SourceList.cs | 5 +- .../List/SourceListEditConvenienceEx.cs | 73 +- src/DynamicData/List/SourceListEx.cs | 11 +- src/DynamicData/ObservableChangeSet.cs | 208 +- src/DynamicData/Platforms/net45/PFilter.cs | 34 +- .../Platforms/net45/PSubscribeMany.cs | 22 +- src/DynamicData/Platforms/net45/PTransform.cs | 52 +- .../Platforms/net45/ParallelOperators.cs | 103 +- .../CompilerFeatureRequiredAttribute.cs | 15 +- 264 files changed, 2698 insertions(+), 6502 deletions(-) create mode 100644 src/DynamicData/Internal/ExceptionMixins.cs diff --git a/.editorconfig b/.editorconfig index 9881231de..ad41e611a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,26 +10,39 @@ root = true insert_final_newline = true indent_style = space indent_size = 4 -dotnet_style_operator_placement_when_wrapping = beginning_of_line -tab_width = 4 -end_of_line = crlf -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion -dotnet_style_prefer_auto_properties = true:suggestion -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_compound_assignment = true:suggestion -dotnet_style_prefer_simplified_interpolation = true:suggestion -dotnet_style_namespace_match_folder = true:suggestion -dotnet_style_prefer_collection_expression = true:suggestion -dotnet_diagnostic.CA2237.severity = none +dotnet_diagnostic.CA1027.severity=error +dotnet_diagnostic.CA1062.severity=error +dotnet_diagnostic.CA1064.severity=error +dotnet_diagnostic.CA1066.severity=error +dotnet_diagnostic.CA1067.severity=error +dotnet_diagnostic.CA1068.severity=error +dotnet_diagnostic.CA1069.severity=warning +dotnet_diagnostic.CA2013.severity=error +dotnet_diagnostic.CA1802.severity=error +dotnet_diagnostic.CA1813.severity=error +dotnet_diagnostic.CA1814.severity=error +dotnet_diagnostic.CA1815.severity=error +dotnet_diagnostic.CA1822.severity=error +dotnet_diagnostic.CA1827.severity=error +dotnet_diagnostic.CA1828.severity=error +dotnet_diagnostic.CA1826.severity=error +dotnet_diagnostic.CA1829.severity=error +dotnet_diagnostic.CA1830.severity=error +dotnet_diagnostic.CA1831.severity=error +dotnet_diagnostic.CA1832.severity=error +dotnet_diagnostic.CA1833.severity=error +dotnet_diagnostic.CA1834.severity=error +dotnet_diagnostic.CA1835.severity=error +dotnet_diagnostic.CA1836.severity=error +dotnet_diagnostic.CA1837.severity=error +dotnet_diagnostic.CA1838.severity=error +dotnet_diagnostic.CA2015.severity=error +dotnet_diagnostic.CA2012.severity=error +dotnet_diagnostic.CA2011.severity=error +dotnet_diagnostic.CA2009.severity=error +dotnet_diagnostic.CA2008.severity=error +dotnet_diagnostic.CA2007.severity=warning +dotnet_diagnostic.CA2000.severity=suggestion [project.json] indent_size = 2 @@ -37,6 +50,8 @@ indent_size = 2 # C# files [*.cs] # New line preferences +tab_width = 4 +end_of_line = crlf csharp_new_line_before_open_brace = all csharp_new_line_before_else = true csharp_new_line_before_catch = true @@ -71,10 +86,13 @@ csharp_style_var_elsewhere = true:suggestion dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion dotnet_style_predefined_type_for_member_access = true:suggestion +# TO BE REVIEWED +# dotnet_diagnostic.CA2237.severity = none + # name all constant fields using PascalCase dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style +dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style dotnet_naming_symbols.constant_fields.applicable_kinds = field dotnet_naming_symbols.constant_fields.required_modifiers = const dotnet_naming_style.pascal_case_style.capitalization = pascal_case @@ -82,7 +100,7 @@ dotnet_naming_style.pascal_case_style.capitalization = pascal_case # static fields should have s_ prefix dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields -dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style +dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style dotnet_naming_symbols.static_fields.applicable_kinds = field dotnet_naming_symbols.static_fields.required_modifiers = static dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected @@ -92,7 +110,7 @@ dotnet_naming_style.static_prefix_style.capitalization = camel_case # internal and private fields should be _camelCase dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields -dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style +dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style dotnet_naming_symbols.private_internal_fields.applicable_kinds = field dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal dotnet_naming_style.camel_case_underscore_style.required_prefix = _ @@ -107,6 +125,12 @@ csharp_preserve_single_line_statements = false:none csharp_prefer_static_local_function = true:suggestion csharp_prefer_simple_using_statement = false:none csharp_style_prefer_switch_expression = true:suggestion +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +dotnet_style_prefer_collection_expression = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line # Code quality dotnet_style_readonly_field = true:suggestion @@ -125,6 +149,10 @@ dotnet_style_prefer_auto_properties = true:suggestion dotnet_style_prefer_conditional_expression_over_assignment = true:silent dotnet_style_prefer_conditional_expression_over_return = true:silent csharp_prefer_simple_default_expression = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_namespace_match_folder = true:suggestion # Expression-bodied members csharp_style_expression_bodied_methods = true:suggestion @@ -176,531 +204,321 @@ csharp_space_between_square_brackets = false # analyzers dotnet_diagnostic.AvoidAsyncVoid.severity = suggestion -dotnet_diagnostic.AvoidAsyncVoid.severity = suggestion - -dotnet_diagnostic.CA1001.severity = suggestion +dotnet_diagnostic.CA1000.severity = none +dotnet_diagnostic.CA1001.severity = error dotnet_diagnostic.CA1009.severity = error - dotnet_diagnostic.CA1016.severity = error - +dotnet_diagnostic.CA1030.severity = none +dotnet_diagnostic.CA1031.severity = none +dotnet_diagnostic.CA1033.severity = none dotnet_diagnostic.CA1036.severity = none - dotnet_diagnostic.CA1049.severity = error - dotnet_diagnostic.CA1056.severity = suggestion - dotnet_diagnostic.CA1060.severity = error - dotnet_diagnostic.CA1061.severity = error - dotnet_diagnostic.CA1063.severity = error - dotnet_diagnostic.CA1065.severity = error - dotnet_diagnostic.CA1301.severity = error - +dotnet_diagnostic.CA1303.severity = none +dotnet_diagnostic.CA1308.severity = none dotnet_diagnostic.CA1400.severity = error - dotnet_diagnostic.CA1401.severity = error - dotnet_diagnostic.CA1403.severity = error - dotnet_diagnostic.CA1404.severity = error - dotnet_diagnostic.CA1405.severity = error - dotnet_diagnostic.CA1410.severity = error - dotnet_diagnostic.CA1415.severity = error - dotnet_diagnostic.CA1507.severity = error - dotnet_diagnostic.CA1710.severity = suggestion - dotnet_diagnostic.CA1716.severity = suggestion - dotnet_diagnostic.CA1724.severity = none - dotnet_diagnostic.CA1801.severity = error - dotnet_diagnostic.CA1810.severity = none - dotnet_diagnostic.CA1821.severity = error - dotnet_diagnostic.CA1900.severity = error - dotnet_diagnostic.CA1901.severity = error - +dotnet_diagnostic.CA2000.severity = none dotnet_diagnostic.CA2002.severity = error - dotnet_diagnostic.CA2007.severity = none - dotnet_diagnostic.CA2100.severity = error - dotnet_diagnostic.CA2101.severity = error - dotnet_diagnostic.CA2108.severity = error - dotnet_diagnostic.CA2111.severity = error - dotnet_diagnostic.CA2112.severity = error - dotnet_diagnostic.CA2114.severity = error - dotnet_diagnostic.CA2116.severity = error - dotnet_diagnostic.CA2117.severity = error - dotnet_diagnostic.CA2122.severity = error - dotnet_diagnostic.CA2123.severity = error - dotnet_diagnostic.CA2124.severity = error - dotnet_diagnostic.CA2126.severity = error - dotnet_diagnostic.CA2131.severity = error - dotnet_diagnostic.CA2132.severity = error - dotnet_diagnostic.CA2133.severity = error - dotnet_diagnostic.CA2134.severity = error - dotnet_diagnostic.CA2137.severity = error - dotnet_diagnostic.CA2138.severity = error - dotnet_diagnostic.CA2140.severity = error - dotnet_diagnostic.CA2141.severity = error - dotnet_diagnostic.CA2146.severity = error - dotnet_diagnostic.CA2147.severity = error - dotnet_diagnostic.CA2149.severity = error - dotnet_diagnostic.CA2200.severity = error - dotnet_diagnostic.CA2202.severity = error - dotnet_diagnostic.CA2207.severity = error - dotnet_diagnostic.CA2212.severity = error - -dotnet_diagnostic.CA2213.severity = suggestion - -dotnet_diagnostic.CA2214.severity = suggestion - +dotnet_diagnostic.CA2213.severity = error +dotnet_diagnostic.CA2214.severity = error dotnet_diagnostic.CA2216.severity = error - dotnet_diagnostic.CA2220.severity = error - dotnet_diagnostic.CA2229.severity = error - dotnet_diagnostic.CA2231.severity = error - dotnet_diagnostic.CA2232.severity = error - dotnet_diagnostic.CA2235.severity = error - dotnet_diagnostic.CA2236.severity = error - dotnet_diagnostic.CA2237.severity = error - dotnet_diagnostic.CA2238.severity = error - dotnet_diagnostic.CA2240.severity = error - dotnet_diagnostic.CA2241.severity = error - dotnet_diagnostic.CA2242.severity = error dotnet_diagnostic.RCS1001.severity = error - dotnet_diagnostic.RCS1018.severity = error - dotnet_diagnostic.RCS1037.severity = error - dotnet_diagnostic.RCS1055.severity = error - dotnet_diagnostic.RCS1062.severity = error - dotnet_diagnostic.RCS1066.severity = error - dotnet_diagnostic.RCS1069.severity = error - dotnet_diagnostic.RCS1071.severity = error - dotnet_diagnostic.RCS1074.severity = error - dotnet_diagnostic.RCS1090.severity = error - dotnet_diagnostic.RCS1138.severity = error - dotnet_diagnostic.RCS1139.severity = error - +dotnet_diagnostic.RCS1163.severity = suggestion dotnet_diagnostic.RCS1168.severity = suggestion - dotnet_diagnostic.RCS1188.severity = error - dotnet_diagnostic.RCS1201.severity = error - dotnet_diagnostic.RCS1207.severity = error - dotnet_diagnostic.RCS1211.severity = error - dotnet_diagnostic.RCS1507.severity = error dotnet_diagnostic.SA1000.severity = error - dotnet_diagnostic.SA1001.severity = error - dotnet_diagnostic.SA1002.severity = error - dotnet_diagnostic.SA1003.severity = error - dotnet_diagnostic.SA1004.severity = error - dotnet_diagnostic.SA1005.severity = error - dotnet_diagnostic.SA1006.severity = error - dotnet_diagnostic.SA1007.severity = error - dotnet_diagnostic.SA1008.severity = error - dotnet_diagnostic.SA1009.severity = error - -dotnet_diagnostic.SA1010.severity = error - +dotnet_diagnostic.SA1010.severity = none dotnet_diagnostic.SA1011.severity = error - dotnet_diagnostic.SA1012.severity = error - dotnet_diagnostic.SA1013.severity = error - dotnet_diagnostic.SA1014.severity = error - dotnet_diagnostic.SA1015.severity = error - dotnet_diagnostic.SA1016.severity = error - dotnet_diagnostic.SA1017.severity = error - dotnet_diagnostic.SA1018.severity = error - dotnet_diagnostic.SA1019.severity = error - dotnet_diagnostic.SA1020.severity = error - dotnet_diagnostic.SA1021.severity = error - dotnet_diagnostic.SA1022.severity = error - dotnet_diagnostic.SA1023.severity = error - dotnet_diagnostic.SA1024.severity = error - dotnet_diagnostic.SA1025.severity = error - dotnet_diagnostic.SA1026.severity = error - dotnet_diagnostic.SA1027.severity = error - dotnet_diagnostic.SA1028.severity = error - dotnet_diagnostic.SA1100.severity = error - dotnet_diagnostic.SA1101.severity = none - dotnet_diagnostic.SA1102.severity = error - dotnet_diagnostic.SA1103.severity = error - dotnet_diagnostic.SA1104.severity = error - dotnet_diagnostic.SA1105.severity = error - dotnet_diagnostic.SA1106.severity = error - dotnet_diagnostic.SA1107.severity = error - dotnet_diagnostic.SA1108.severity = error - dotnet_diagnostic.SA1110.severity = error - dotnet_diagnostic.SA1111.severity = error - dotnet_diagnostic.SA1112.severity = error - dotnet_diagnostic.SA1113.severity = error - dotnet_diagnostic.SA1114.severity = error - dotnet_diagnostic.SA1115.severity = error - -dotnet_diagnostic.SA1116.severity = none - -dotnet_diagnostic.SA1117.severity = none - +dotnet_diagnostic.SA1116.severity = error +dotnet_diagnostic.SA1117.severity = error dotnet_diagnostic.SA1118.severity = error - dotnet_diagnostic.SA1119.severity = error - dotnet_diagnostic.SA1120.severity = error - dotnet_diagnostic.SA1121.severity = error - dotnet_diagnostic.SA1122.severity = error - dotnet_diagnostic.SA1123.severity = error - dotnet_diagnostic.SA1124.severity = error - dotnet_diagnostic.SA1125.severity = error - dotnet_diagnostic.SA1127.severity = error - dotnet_diagnostic.SA1128.severity = error - dotnet_diagnostic.SA1129.severity = error - dotnet_diagnostic.SA1130.severity = error - dotnet_diagnostic.SA1131.severity = error - dotnet_diagnostic.SA1132.severity = error - dotnet_diagnostic.SA1133.severity = error - dotnet_diagnostic.SA1134.severity = error - dotnet_diagnostic.SA1135.severity = error - dotnet_diagnostic.SA1136.severity = error - dotnet_diagnostic.SA1137.severity = error - dotnet_diagnostic.SA1139.severity = error - dotnet_diagnostic.SA1200.severity = none - -dotnet_diagnostic.SA1201.severity = none - -dotnet_diagnostic.SA1202.severity = silent - +dotnet_diagnostic.SA1201.severity = error +dotnet_diagnostic.SA1202.severity = error dotnet_diagnostic.SA1203.severity = error - -dotnet_diagnostic.SA1204.severity = none - +dotnet_diagnostic.SA1204.severity = error dotnet_diagnostic.SA1205.severity = error - dotnet_diagnostic.SA1206.severity = error - dotnet_diagnostic.SA1207.severity = error - dotnet_diagnostic.SA1208.severity = error - dotnet_diagnostic.SA1209.severity = error - dotnet_diagnostic.SA1210.severity = error - dotnet_diagnostic.SA1211.severity = error - dotnet_diagnostic.SA1212.severity = error - dotnet_diagnostic.SA1213.severity = error - dotnet_diagnostic.SA1214.severity = error - dotnet_diagnostic.SA1216.severity = error - dotnet_diagnostic.SA1217.severity = error - dotnet_diagnostic.SA1300.severity = error - dotnet_diagnostic.SA1302.severity = error - dotnet_diagnostic.SA1303.severity = error - dotnet_diagnostic.SA1304.severity = error - dotnet_diagnostic.SA1306.severity = none - dotnet_diagnostic.SA1307.severity = error - dotnet_diagnostic.SA1308.severity = error - dotnet_diagnostic.SA1309.severity = none - dotnet_diagnostic.SA1310.severity = error - dotnet_diagnostic.SA1311.severity = none - dotnet_diagnostic.SA1312.severity = error - dotnet_diagnostic.SA1313.severity = error - dotnet_diagnostic.SA1314.severity = error - +dotnet_diagnostic.SA1316.severity = none dotnet_diagnostic.SA1400.severity = error - dotnet_diagnostic.SA1401.severity = error - -dotnet_diagnostic.SA1402.severity = none - +dotnet_diagnostic.SA1402.severity = error dotnet_diagnostic.SA1403.severity = error - dotnet_diagnostic.SA1404.severity = error - dotnet_diagnostic.SA1405.severity = error - dotnet_diagnostic.SA1406.severity = error - dotnet_diagnostic.SA1407.severity = error - dotnet_diagnostic.SA1408.severity = error - dotnet_diagnostic.SA1410.severity = error - dotnet_diagnostic.SA1411.severity = error - dotnet_diagnostic.SA1413.severity = none - dotnet_diagnostic.SA1500.severity = error - -dotnet_diagnostic.SA1501.severity = none - +dotnet_diagnostic.SA1501.severity = error dotnet_diagnostic.SA1502.severity = error - -dotnet_diagnostic.SA1503.severity = none - +dotnet_diagnostic.SA1503.severity = error dotnet_diagnostic.SA1504.severity = error - dotnet_diagnostic.SA1505.severity = error - dotnet_diagnostic.SA1506.severity = error - dotnet_diagnostic.SA1507.severity = error - -dotnet_diagnostic.SA1508.severity = none - +dotnet_diagnostic.SA1508.severity = error dotnet_diagnostic.SA1509.severity = error - dotnet_diagnostic.SA1510.severity = error - dotnet_diagnostic.SA1511.severity = error - dotnet_diagnostic.SA1512.severity = error - dotnet_diagnostic.SA1513.severity = error - dotnet_diagnostic.SA1514.severity = error - dotnet_diagnostic.SA1515.severity = error - dotnet_diagnostic.SA1516.severity = error - dotnet_diagnostic.SA1517.severity = error - dotnet_diagnostic.SA1518.severity = error - dotnet_diagnostic.SA1519.severity = error - dotnet_diagnostic.SA1520.severity = error - dotnet_diagnostic.SA1600.severity = error - dotnet_diagnostic.SA1601.severity = error - dotnet_diagnostic.SA1602.severity = error - dotnet_diagnostic.SA1604.severity = error - dotnet_diagnostic.SA1605.severity = error - dotnet_diagnostic.SA1606.severity = error - dotnet_diagnostic.SA1607.severity = error - dotnet_diagnostic.SA1608.severity = error - dotnet_diagnostic.SA1610.severity = error - dotnet_diagnostic.SA1611.severity = error - dotnet_diagnostic.SA1612.severity = error - dotnet_diagnostic.SA1613.severity = error - dotnet_diagnostic.SA1614.severity = error - dotnet_diagnostic.SA1615.severity = error - dotnet_diagnostic.SA1616.severity = error - dotnet_diagnostic.SA1617.severity = error - dotnet_diagnostic.SA1618.severity = error - dotnet_diagnostic.SA1619.severity = error - dotnet_diagnostic.SA1620.severity = error - dotnet_diagnostic.SA1621.severity = error - dotnet_diagnostic.SA1622.severity = error - dotnet_diagnostic.SA1623.severity = error - dotnet_diagnostic.SA1624.severity = error - dotnet_diagnostic.SA1625.severity = error - dotnet_diagnostic.SA1626.severity = error - dotnet_diagnostic.SA1627.severity = error - dotnet_diagnostic.SA1629.severity = error - dotnet_diagnostic.SA1633.severity = error - dotnet_diagnostic.SA1634.severity = error - dotnet_diagnostic.SA1635.severity = error - dotnet_diagnostic.SA1636.severity = error - dotnet_diagnostic.SA1637.severity = none - dotnet_diagnostic.SA1638.severity = none - dotnet_diagnostic.SA1640.severity = error - dotnet_diagnostic.SA1641.severity = error - dotnet_diagnostic.SA1642.severity = error - dotnet_diagnostic.SA1643.severity = error - dotnet_diagnostic.SA1649.severity = error - dotnet_diagnostic.SA1651.severity = error dotnet_diagnostic.SX1101.severity = error - dotnet_diagnostic.SX1309.severity = error - -dotnet_diagnostic.SX1623.severity = none dotnet_diagnostic.SX1309S.severity=silent -csharp_style_namespace_declarations = block_scoped:silent -csharp_style_prefer_method_group_conversion = true:silent -csharp_style_prefer_top_level_statements = true:silent -csharp_style_prefer_primary_constructors = true:suggestion +dotnet_diagnostic.SX1623.severity = none +dotnet_diagnostic.RCS1102.severity=error +dotnet_diagnostic.RCS1166.severity=error +dotnet_diagnostic.RCS1078i.severity=error +dotnet_diagnostic.RCS1248.severity=error +dotnet_diagnostic.RCS1080.severity=error +dotnet_diagnostic.RCS1077.severity=error +dotnet_diagnostic.CA1825.severity=error +dotnet_diagnostic.CA1812.severity=error +dotnet_diagnostic.CA1805.severity=error dotnet_diagnostic.RCS1194.severity = none +dotnet_diagnostic.RCS1197.severity=error +dotnet_diagnostic.RCS1198.severity=none +dotnet_diagnostic.RCS1231.severity=suggestion +dotnet_diagnostic.RCS1235.severity=error +dotnet_diagnostic.RCS1242.severity=error +dotnet_diagnostic.CA2016.severity=warning +dotnet_diagnostic.CA2014.severity=error +dotnet_diagnostic.RCS1010.severity=error +dotnet_diagnostic.RCS1006.severity=error +dotnet_diagnostic.RCS1005.severity=error +dotnet_diagnostic.RCS1020.severity=error +dotnet_diagnostic.RCS1049.severity=warning +dotnet_diagnostic.RCS1058.severity=warning +dotnet_diagnostic.RCS1068.severity=warning +dotnet_diagnostic.RCS1073.severity=warning +dotnet_diagnostic.RCS1084.severity=error +dotnet_diagnostic.RCS1085.severity=error +dotnet_diagnostic.RCS1105.severity=error +dotnet_diagnostic.RCS1112.severity=error +dotnet_diagnostic.RCS1128.severity=error +dotnet_diagnostic.RCS1143.severity=error +dotnet_diagnostic.RCS1171.severity=error +dotnet_diagnostic.RCS1173.severity=error +dotnet_diagnostic.RCS1176.severity=error +dotnet_diagnostic.RCS1177.severity=error +dotnet_diagnostic.RCS1179.severity=error +dotnet_diagnostic.RCS1180.severity=warning +dotnet_diagnostic.RCS1190.severity=error +dotnet_diagnostic.RCS1195.severity=error +dotnet_diagnostic.RCS1214.severity=error + +dotnet_diagnostic.IDE1006.severity=none # C++ Files [*.{cpp,h,in}] @@ -728,3 +546,5 @@ indent_size = 2 end_of_line = lf [*.{cmd, bat}] end_of_line = crlf + +vsspell_dictionary_languages = en-US \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 63a4a3de8..85df63e75 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ true - $(NoWarn);1591;1701;1702;1705;VSX1000;SA1010 + $(NoWarn);1591;1701;1702;1705;VSX1000 AnyCPU $(MSBuildProjectName.Contains('Tests')) $(MSBuildProjectName.Contains('Benchmarks')) diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet6_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet6_0.verified.txt index 539e1c744..6bfeaf9ee 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet6_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet6_0.verified.txt @@ -12,8 +12,8 @@ namespace DynamicData.Aggregation public bool Equals(DynamicData.Aggregation.AggregateItem other) { } public override bool Equals(object? obj) { } public override int GetHashCode() { } - public static bool operator !=(DynamicData.Aggregation.AggregateItem left, DynamicData.Aggregation.AggregateItem right) { } - public static bool operator ==(DynamicData.Aggregation.AggregateItem left, DynamicData.Aggregation.AggregateItem right) { } + public static bool operator !=(in DynamicData.Aggregation.AggregateItem left, in DynamicData.Aggregation.AggregateItem right) { } + public static bool operator ==(in DynamicData.Aggregation.AggregateItem left, in DynamicData.Aggregation.AggregateItem right) { } } public enum AggregateType { @@ -669,7 +669,7 @@ namespace DynamicData public Change(DynamicData.ListChangeReason reason, System.Collections.Generic.IEnumerable items, int index = -1) { } public Change(DynamicData.ListChangeReason reason, T current, int index = -1) { } public Change(T current, int currentIndex, int previousIndex) { } - public Change(DynamicData.ListChangeReason reason, T current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public Change(DynamicData.ListChangeReason reason, T current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public DynamicData.ItemChange Item { get; } public DynamicData.RangeChange Range { get; } public DynamicData.ListChangeReason Reason { get; } @@ -687,7 +687,7 @@ namespace DynamicData { public Change(DynamicData.ChangeReason reason, TKey key, TObject current, int index = -1) { } public Change(TKey key, TObject current, int currentIndex, int previousIndex) { } - public Change(DynamicData.ChangeReason reason, TKey key, TObject current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public Change(DynamicData.ChangeReason reason, TKey key, TObject current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public TObject Current { get; } public int CurrentIndex { get; } public TKey Key { get; } @@ -698,8 +698,8 @@ namespace DynamicData public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Change left, DynamicData.Change right) { } - public static bool operator ==(DynamicData.Change left, DynamicData.Change right) { } + public static bool operator !=(in DynamicData.Change left, in DynamicData.Change right) { } + public static bool operator ==(in DynamicData.Change left, in DynamicData.Change right) { } } public static class EnumerableEx { @@ -763,13 +763,13 @@ namespace DynamicData public interface IChangeSetAdaptor where T : notnull { - void Adapt(DynamicData.IChangeSet change); + void Adapt(DynamicData.IChangeSet changes); } public interface IChangeSetAdaptor where TObject : notnull where TKey : notnull { - void Adapt(DynamicData.IChangeSet change); + void Adapt(DynamicData.IChangeSet changes); } public interface IChangeSet : DynamicData.IChangeSet, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable where TObject : notnull @@ -901,7 +901,7 @@ namespace DynamicData where TObject : notnull where TKey : notnull { - void Adapt(DynamicData.ISortedChangeSet change); + void Adapt(DynamicData.ISortedChangeSet changes); } public interface ISortedChangeSet : DynamicData.IChangeSet, DynamicData.IChangeSet, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable where TObject : notnull @@ -996,7 +996,7 @@ namespace DynamicData { public static readonly DynamicData.ItemChange Empty; public ItemChange(DynamicData.ListChangeReason reason, T current, int currentIndex) { } - public ItemChange(DynamicData.ListChangeReason reason, T current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public ItemChange(DynamicData.ListChangeReason reason, T current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public T Current { get; } public int CurrentIndex { get; } public DynamicData.Kernel.Optional Previous { get; } @@ -1006,8 +1006,8 @@ namespace DynamicData public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.ItemChange left, DynamicData.ItemChange right) { } - public static bool operator ==(DynamicData.ItemChange left, DynamicData.ItemChange right) { } + public static bool operator !=(in DynamicData.ItemChange left, in DynamicData.ItemChange right) { } + public static bool operator ==(in DynamicData.ItemChange left, in DynamicData.ItemChange right) { } } public enum ListChangeReason { @@ -1061,7 +1061,7 @@ namespace DynamicData where TKey : notnull { public Node(TObject item, TKey key) { } - public Node(TObject item, TKey key, DynamicData.Kernel.Optional> parent) { } + public Node(TObject item, TKey key, in DynamicData.Kernel.Optional> parent) { } public DynamicData.IObservableCache, TKey> Children { get; } public int Depth { get; } public bool IsRoot { get; } @@ -2523,8 +2523,8 @@ namespace DynamicData.Kernel public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Kernel.ItemWithIndex left, DynamicData.Kernel.ItemWithIndex right) { } - public static bool operator ==(DynamicData.Kernel.ItemWithIndex left, DynamicData.Kernel.ItemWithIndex right) { } + public static bool operator !=(in DynamicData.Kernel.ItemWithIndex left, in DynamicData.Kernel.ItemWithIndex right) { } + public static bool operator ==(in DynamicData.Kernel.ItemWithIndex left, in DynamicData.Kernel.ItemWithIndex right) { } } public readonly struct ItemWithValue : System.IEquatable> { @@ -2535,8 +2535,8 @@ namespace DynamicData.Kernel public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Kernel.ItemWithValue left, DynamicData.Kernel.ItemWithValue right) { } - public static bool operator ==(DynamicData.Kernel.ItemWithValue left, DynamicData.Kernel.ItemWithValue right) { } + public static bool operator !=(in DynamicData.Kernel.ItemWithValue left, in DynamicData.Kernel.ItemWithValue right) { } + public static bool operator ==(in DynamicData.Kernel.ItemWithValue left, in DynamicData.Kernel.ItemWithValue right) { } } public sealed class OptionElse { @@ -2544,34 +2544,34 @@ namespace DynamicData.Kernel } public static class OptionExtensions { - public static DynamicData.Kernel.Optional Convert(this DynamicData.Kernel.Optional source, System.Func> converter) + public static DynamicData.Kernel.Optional Convert(in this DynamicData.Kernel.Optional source, System.Func> converter) where TSource : notnull where TDestination : notnull { } - public static DynamicData.Kernel.Optional Convert(this DynamicData.Kernel.Optional source, System.Func converter) + public static DynamicData.Kernel.Optional Convert(in this DynamicData.Kernel.Optional source, System.Func converter) where TSource : notnull where TDestination : notnull { } - public static TDestination? ConvertOr(this DynamicData.Kernel.Optional source, System.Func converter, System.Func fallbackConverter) + public static TDestination? ConvertOr(in this DynamicData.Kernel.Optional source, System.Func converter, System.Func fallbackConverter) where TSource : notnull { } public static DynamicData.Kernel.Optional FirstOrOptional(this System.Collections.Generic.IEnumerable source, System.Func selector) where T : notnull { } - public static DynamicData.Kernel.OptionElse IfHasValue(this DynamicData.Kernel.Optional source, System.Action action) + public static DynamicData.Kernel.OptionElse IfHasValue(in this DynamicData.Kernel.Optional source, System.Action action) where T : notnull { } public static DynamicData.Kernel.OptionElse IfHasValue(this DynamicData.Kernel.Optional? source, System.Action action) where T : notnull { } public static DynamicData.Kernel.Optional Lookup(this System.Collections.Generic.IDictionary source, TKey key) where TValue : notnull { } - public static DynamicData.Kernel.Optional OrElse(this DynamicData.Kernel.Optional source, System.Func> fallbackOperation) + public static DynamicData.Kernel.Optional OrElse(in this DynamicData.Kernel.Optional source, System.Func> fallbackOperation) where T : notnull { } public static bool RemoveIfContained(this System.Collections.Generic.IDictionary source, TKey key) { } public static System.Collections.Generic.IEnumerable SelectValues(this System.Collections.Generic.IEnumerable> source) where T : notnull { } - public static T ValueOr(this DynamicData.Kernel.Optional source, System.Func valueSelector) + public static T ValueOr(in this DynamicData.Kernel.Optional source, System.Func valueSelector) where T : notnull { } public static T ValueOr(this T? source, T defaultValue) where T : struct { } - public static T? ValueOrDefault(this DynamicData.Kernel.Optional source) + public static T? ValueOrDefault(in this DynamicData.Kernel.Optional source) where T : notnull { } - public static T ValueOrThrow(this DynamicData.Kernel.Optional source, System.Func exceptionGenerator) + public static T ValueOrThrow(in this DynamicData.Kernel.Optional source, System.Func exceptionGenerator) where T : notnull { } } public static class OptionObservableExtensions @@ -2617,12 +2617,12 @@ namespace DynamicData.Kernel public override int GetHashCode() { } public override string? ToString() { } public static DynamicData.Kernel.Optional Create(T? value) { } - public static T? FromOptional(DynamicData.Kernel.Optional value) { } + public static T? FromOptional(in DynamicData.Kernel.Optional value) { } public static DynamicData.Kernel.Optional ToOptional(T? value) { } - public static T? op_Explicit(DynamicData.Kernel.Optional value) { } + public static T? op_Explicit(in DynamicData.Kernel.Optional value) { } public static DynamicData.Kernel.Optional op_Implicit(T? value) { } - public static bool operator !=(DynamicData.Kernel.Optional left, DynamicData.Kernel.Optional right) { } - public static bool operator ==(DynamicData.Kernel.Optional left, DynamicData.Kernel.Optional right) { } + public static bool operator !=(in DynamicData.Kernel.Optional left, in DynamicData.Kernel.Optional right) { } + public static bool operator ==(in DynamicData.Kernel.Optional left, in DynamicData.Kernel.Optional right) { } } } namespace DynamicData.List diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet7_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet7_0.verified.txt index 467ae974f..bff2365af 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet7_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet7_0.verified.txt @@ -12,8 +12,8 @@ namespace DynamicData.Aggregation public bool Equals(DynamicData.Aggregation.AggregateItem other) { } public override bool Equals(object? obj) { } public override int GetHashCode() { } - public static bool operator !=(DynamicData.Aggregation.AggregateItem left, DynamicData.Aggregation.AggregateItem right) { } - public static bool operator ==(DynamicData.Aggregation.AggregateItem left, DynamicData.Aggregation.AggregateItem right) { } + public static bool operator !=(in DynamicData.Aggregation.AggregateItem left, in DynamicData.Aggregation.AggregateItem right) { } + public static bool operator ==(in DynamicData.Aggregation.AggregateItem left, in DynamicData.Aggregation.AggregateItem right) { } } public enum AggregateType { @@ -669,7 +669,7 @@ namespace DynamicData public Change(DynamicData.ListChangeReason reason, System.Collections.Generic.IEnumerable items, int index = -1) { } public Change(DynamicData.ListChangeReason reason, T current, int index = -1) { } public Change(T current, int currentIndex, int previousIndex) { } - public Change(DynamicData.ListChangeReason reason, T current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public Change(DynamicData.ListChangeReason reason, T current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public DynamicData.ItemChange Item { get; } public DynamicData.RangeChange Range { get; } public DynamicData.ListChangeReason Reason { get; } @@ -687,7 +687,7 @@ namespace DynamicData { public Change(DynamicData.ChangeReason reason, TKey key, TObject current, int index = -1) { } public Change(TKey key, TObject current, int currentIndex, int previousIndex) { } - public Change(DynamicData.ChangeReason reason, TKey key, TObject current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public Change(DynamicData.ChangeReason reason, TKey key, TObject current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public TObject Current { get; } public int CurrentIndex { get; } public TKey Key { get; } @@ -698,8 +698,8 @@ namespace DynamicData public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Change left, DynamicData.Change right) { } - public static bool operator ==(DynamicData.Change left, DynamicData.Change right) { } + public static bool operator !=(in DynamicData.Change left, in DynamicData.Change right) { } + public static bool operator ==(in DynamicData.Change left, in DynamicData.Change right) { } } public static class EnumerableEx { @@ -763,13 +763,13 @@ namespace DynamicData public interface IChangeSetAdaptor where T : notnull { - void Adapt(DynamicData.IChangeSet change); + void Adapt(DynamicData.IChangeSet changes); } public interface IChangeSetAdaptor where TObject : notnull where TKey : notnull { - void Adapt(DynamicData.IChangeSet change); + void Adapt(DynamicData.IChangeSet changes); } public interface IChangeSet : DynamicData.IChangeSet, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable where TObject : notnull @@ -901,7 +901,7 @@ namespace DynamicData where TObject : notnull where TKey : notnull { - void Adapt(DynamicData.ISortedChangeSet change); + void Adapt(DynamicData.ISortedChangeSet changes); } public interface ISortedChangeSet : DynamicData.IChangeSet, DynamicData.IChangeSet, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable where TObject : notnull @@ -996,7 +996,7 @@ namespace DynamicData { public static readonly DynamicData.ItemChange Empty; public ItemChange(DynamicData.ListChangeReason reason, T current, int currentIndex) { } - public ItemChange(DynamicData.ListChangeReason reason, T current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public ItemChange(DynamicData.ListChangeReason reason, T current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public T Current { get; } public int CurrentIndex { get; } public DynamicData.Kernel.Optional Previous { get; } @@ -1006,8 +1006,8 @@ namespace DynamicData public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.ItemChange left, DynamicData.ItemChange right) { } - public static bool operator ==(DynamicData.ItemChange left, DynamicData.ItemChange right) { } + public static bool operator !=(in DynamicData.ItemChange left, in DynamicData.ItemChange right) { } + public static bool operator ==(in DynamicData.ItemChange left, in DynamicData.ItemChange right) { } } public enum ListChangeReason { @@ -1061,7 +1061,7 @@ namespace DynamicData where TKey : notnull { public Node(TObject item, TKey key) { } - public Node(TObject item, TKey key, DynamicData.Kernel.Optional> parent) { } + public Node(TObject item, TKey key, in DynamicData.Kernel.Optional> parent) { } public DynamicData.IObservableCache, TKey> Children { get; } public int Depth { get; } public bool IsRoot { get; } @@ -2523,8 +2523,8 @@ namespace DynamicData.Kernel public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Kernel.ItemWithIndex left, DynamicData.Kernel.ItemWithIndex right) { } - public static bool operator ==(DynamicData.Kernel.ItemWithIndex left, DynamicData.Kernel.ItemWithIndex right) { } + public static bool operator !=(in DynamicData.Kernel.ItemWithIndex left, in DynamicData.Kernel.ItemWithIndex right) { } + public static bool operator ==(in DynamicData.Kernel.ItemWithIndex left, in DynamicData.Kernel.ItemWithIndex right) { } } public readonly struct ItemWithValue : System.IEquatable> { @@ -2535,8 +2535,8 @@ namespace DynamicData.Kernel public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Kernel.ItemWithValue left, DynamicData.Kernel.ItemWithValue right) { } - public static bool operator ==(DynamicData.Kernel.ItemWithValue left, DynamicData.Kernel.ItemWithValue right) { } + public static bool operator !=(in DynamicData.Kernel.ItemWithValue left, in DynamicData.Kernel.ItemWithValue right) { } + public static bool operator ==(in DynamicData.Kernel.ItemWithValue left, in DynamicData.Kernel.ItemWithValue right) { } } public sealed class OptionElse { @@ -2544,34 +2544,34 @@ namespace DynamicData.Kernel } public static class OptionExtensions { - public static DynamicData.Kernel.Optional Convert(this DynamicData.Kernel.Optional source, System.Func> converter) + public static DynamicData.Kernel.Optional Convert(in this DynamicData.Kernel.Optional source, System.Func> converter) where TSource : notnull where TDestination : notnull { } - public static DynamicData.Kernel.Optional Convert(this DynamicData.Kernel.Optional source, System.Func converter) + public static DynamicData.Kernel.Optional Convert(in this DynamicData.Kernel.Optional source, System.Func converter) where TSource : notnull where TDestination : notnull { } - public static TDestination? ConvertOr(this DynamicData.Kernel.Optional source, System.Func converter, System.Func fallbackConverter) + public static TDestination? ConvertOr(in this DynamicData.Kernel.Optional source, System.Func converter, System.Func fallbackConverter) where TSource : notnull { } public static DynamicData.Kernel.Optional FirstOrOptional(this System.Collections.Generic.IEnumerable source, System.Func selector) where T : notnull { } - public static DynamicData.Kernel.OptionElse IfHasValue(this DynamicData.Kernel.Optional source, System.Action action) + public static DynamicData.Kernel.OptionElse IfHasValue(in this DynamicData.Kernel.Optional source, System.Action action) where T : notnull { } public static DynamicData.Kernel.OptionElse IfHasValue(this DynamicData.Kernel.Optional? source, System.Action action) where T : notnull { } public static DynamicData.Kernel.Optional Lookup(this System.Collections.Generic.IDictionary source, TKey key) where TValue : notnull { } - public static DynamicData.Kernel.Optional OrElse(this DynamicData.Kernel.Optional source, System.Func> fallbackOperation) + public static DynamicData.Kernel.Optional OrElse(in this DynamicData.Kernel.Optional source, System.Func> fallbackOperation) where T : notnull { } public static bool RemoveIfContained(this System.Collections.Generic.IDictionary source, TKey key) { } public static System.Collections.Generic.IEnumerable SelectValues(this System.Collections.Generic.IEnumerable> source) where T : notnull { } - public static T ValueOr(this DynamicData.Kernel.Optional source, System.Func valueSelector) + public static T ValueOr(in this DynamicData.Kernel.Optional source, System.Func valueSelector) where T : notnull { } public static T ValueOr(this T? source, T defaultValue) where T : struct { } - public static T? ValueOrDefault(this DynamicData.Kernel.Optional source) + public static T? ValueOrDefault(in this DynamicData.Kernel.Optional source) where T : notnull { } - public static T ValueOrThrow(this DynamicData.Kernel.Optional source, System.Func exceptionGenerator) + public static T ValueOrThrow(in this DynamicData.Kernel.Optional source, System.Func exceptionGenerator) where T : notnull { } } public static class OptionObservableExtensions @@ -2617,12 +2617,12 @@ namespace DynamicData.Kernel public override int GetHashCode() { } public override string? ToString() { } public static DynamicData.Kernel.Optional Create(T? value) { } - public static T? FromOptional(DynamicData.Kernel.Optional value) { } + public static T? FromOptional(in DynamicData.Kernel.Optional value) { } public static DynamicData.Kernel.Optional ToOptional(T? value) { } - public static T? op_Explicit(DynamicData.Kernel.Optional value) { } + public static T? op_Explicit(in DynamicData.Kernel.Optional value) { } public static DynamicData.Kernel.Optional op_Implicit(T? value) { } - public static bool operator !=(DynamicData.Kernel.Optional left, DynamicData.Kernel.Optional right) { } - public static bool operator ==(DynamicData.Kernel.Optional left, DynamicData.Kernel.Optional right) { } + public static bool operator !=(in DynamicData.Kernel.Optional left, in DynamicData.Kernel.Optional right) { } + public static bool operator ==(in DynamicData.Kernel.Optional left, in DynamicData.Kernel.Optional right) { } } } namespace DynamicData.List diff --git a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt index 046c0b5cf..855d913eb 100644 --- a/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt +++ b/src/DynamicData.Tests/API/ApiApprovalTests.DynamicDataTests.DotNet8_0.verified.txt @@ -12,8 +12,8 @@ namespace DynamicData.Aggregation public bool Equals(DynamicData.Aggregation.AggregateItem other) { } public override bool Equals(object? obj) { } public override int GetHashCode() { } - public static bool operator !=(DynamicData.Aggregation.AggregateItem left, DynamicData.Aggregation.AggregateItem right) { } - public static bool operator ==(DynamicData.Aggregation.AggregateItem left, DynamicData.Aggregation.AggregateItem right) { } + public static bool operator !=(in DynamicData.Aggregation.AggregateItem left, in DynamicData.Aggregation.AggregateItem right) { } + public static bool operator ==(in DynamicData.Aggregation.AggregateItem left, in DynamicData.Aggregation.AggregateItem right) { } } public enum AggregateType { @@ -669,7 +669,7 @@ namespace DynamicData public Change(DynamicData.ListChangeReason reason, System.Collections.Generic.IEnumerable items, int index = -1) { } public Change(DynamicData.ListChangeReason reason, T current, int index = -1) { } public Change(T current, int currentIndex, int previousIndex) { } - public Change(DynamicData.ListChangeReason reason, T current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public Change(DynamicData.ListChangeReason reason, T current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public DynamicData.ItemChange Item { get; } public DynamicData.RangeChange Range { get; } public DynamicData.ListChangeReason Reason { get; } @@ -687,7 +687,7 @@ namespace DynamicData { public Change(DynamicData.ChangeReason reason, TKey key, TObject current, int index = -1) { } public Change(TKey key, TObject current, int currentIndex, int previousIndex) { } - public Change(DynamicData.ChangeReason reason, TKey key, TObject current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public Change(DynamicData.ChangeReason reason, TKey key, TObject current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public TObject Current { get; } public int CurrentIndex { get; } public TKey Key { get; } @@ -698,8 +698,8 @@ namespace DynamicData public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Change left, DynamicData.Change right) { } - public static bool operator ==(DynamicData.Change left, DynamicData.Change right) { } + public static bool operator !=(in DynamicData.Change left, in DynamicData.Change right) { } + public static bool operator ==(in DynamicData.Change left, in DynamicData.Change right) { } } public static class EnumerableEx { @@ -763,13 +763,13 @@ namespace DynamicData public interface IChangeSetAdaptor where T : notnull { - void Adapt(DynamicData.IChangeSet change); + void Adapt(DynamicData.IChangeSet changes); } public interface IChangeSetAdaptor where TObject : notnull where TKey : notnull { - void Adapt(DynamicData.IChangeSet change); + void Adapt(DynamicData.IChangeSet changes); } public interface IChangeSet : DynamicData.IChangeSet, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable where TObject : notnull @@ -901,7 +901,7 @@ namespace DynamicData where TObject : notnull where TKey : notnull { - void Adapt(DynamicData.ISortedChangeSet change); + void Adapt(DynamicData.ISortedChangeSet changes); } public interface ISortedChangeSet : DynamicData.IChangeSet, DynamicData.IChangeSet, System.Collections.Generic.IEnumerable>, System.Collections.IEnumerable where TObject : notnull @@ -996,7 +996,7 @@ namespace DynamicData { public static readonly DynamicData.ItemChange Empty; public ItemChange(DynamicData.ListChangeReason reason, T current, int currentIndex) { } - public ItemChange(DynamicData.ListChangeReason reason, T current, DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } + public ItemChange(DynamicData.ListChangeReason reason, T current, in DynamicData.Kernel.Optional previous, int currentIndex = -1, int previousIndex = -1) { } public T Current { get; } public int CurrentIndex { get; } public DynamicData.Kernel.Optional Previous { get; } @@ -1006,8 +1006,8 @@ namespace DynamicData public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.ItemChange left, DynamicData.ItemChange right) { } - public static bool operator ==(DynamicData.ItemChange left, DynamicData.ItemChange right) { } + public static bool operator !=(in DynamicData.ItemChange left, in DynamicData.ItemChange right) { } + public static bool operator ==(in DynamicData.ItemChange left, in DynamicData.ItemChange right) { } } public enum ListChangeReason { @@ -1061,7 +1061,7 @@ namespace DynamicData where TKey : notnull { public Node(TObject item, TKey key) { } - public Node(TObject item, TKey key, DynamicData.Kernel.Optional> parent) { } + public Node(TObject item, TKey key, in DynamicData.Kernel.Optional> parent) { } public DynamicData.IObservableCache, TKey> Children { get; } public int Depth { get; } public bool IsRoot { get; } @@ -2523,8 +2523,8 @@ namespace DynamicData.Kernel public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Kernel.ItemWithIndex left, DynamicData.Kernel.ItemWithIndex right) { } - public static bool operator ==(DynamicData.Kernel.ItemWithIndex left, DynamicData.Kernel.ItemWithIndex right) { } + public static bool operator !=(in DynamicData.Kernel.ItemWithIndex left, in DynamicData.Kernel.ItemWithIndex right) { } + public static bool operator ==(in DynamicData.Kernel.ItemWithIndex left, in DynamicData.Kernel.ItemWithIndex right) { } } public readonly struct ItemWithValue : System.IEquatable> { @@ -2535,8 +2535,8 @@ namespace DynamicData.Kernel public override bool Equals(object? obj) { } public override int GetHashCode() { } public override string ToString() { } - public static bool operator !=(DynamicData.Kernel.ItemWithValue left, DynamicData.Kernel.ItemWithValue right) { } - public static bool operator ==(DynamicData.Kernel.ItemWithValue left, DynamicData.Kernel.ItemWithValue right) { } + public static bool operator !=(in DynamicData.Kernel.ItemWithValue left, in DynamicData.Kernel.ItemWithValue right) { } + public static bool operator ==(in DynamicData.Kernel.ItemWithValue left, in DynamicData.Kernel.ItemWithValue right) { } } public sealed class OptionElse { @@ -2544,34 +2544,34 @@ namespace DynamicData.Kernel } public static class OptionExtensions { - public static DynamicData.Kernel.Optional Convert(this DynamicData.Kernel.Optional source, System.Func> converter) + public static DynamicData.Kernel.Optional Convert(in this DynamicData.Kernel.Optional source, System.Func> converter) where TSource : notnull where TDestination : notnull { } - public static DynamicData.Kernel.Optional Convert(this DynamicData.Kernel.Optional source, System.Func converter) + public static DynamicData.Kernel.Optional Convert(in this DynamicData.Kernel.Optional source, System.Func converter) where TSource : notnull where TDestination : notnull { } - public static TDestination? ConvertOr(this DynamicData.Kernel.Optional source, System.Func converter, System.Func fallbackConverter) + public static TDestination? ConvertOr(in this DynamicData.Kernel.Optional source, System.Func converter, System.Func fallbackConverter) where TSource : notnull { } public static DynamicData.Kernel.Optional FirstOrOptional(this System.Collections.Generic.IEnumerable source, System.Func selector) where T : notnull { } - public static DynamicData.Kernel.OptionElse IfHasValue(this DynamicData.Kernel.Optional source, System.Action action) + public static DynamicData.Kernel.OptionElse IfHasValue(in this DynamicData.Kernel.Optional source, System.Action action) where T : notnull { } public static DynamicData.Kernel.OptionElse IfHasValue(this DynamicData.Kernel.Optional? source, System.Action action) where T : notnull { } public static DynamicData.Kernel.Optional Lookup(this System.Collections.Generic.IDictionary source, TKey key) where TValue : notnull { } - public static DynamicData.Kernel.Optional OrElse(this DynamicData.Kernel.Optional source, System.Func> fallbackOperation) + public static DynamicData.Kernel.Optional OrElse(in this DynamicData.Kernel.Optional source, System.Func> fallbackOperation) where T : notnull { } public static bool RemoveIfContained(this System.Collections.Generic.IDictionary source, TKey key) { } public static System.Collections.Generic.IEnumerable SelectValues(this System.Collections.Generic.IEnumerable> source) where T : notnull { } - public static T ValueOr(this DynamicData.Kernel.Optional source, System.Func valueSelector) + public static T ValueOr(in this DynamicData.Kernel.Optional source, System.Func valueSelector) where T : notnull { } public static T ValueOr(this T? source, T defaultValue) where T : struct { } - public static T? ValueOrDefault(this DynamicData.Kernel.Optional source) + public static T? ValueOrDefault(in this DynamicData.Kernel.Optional source) where T : notnull { } - public static T ValueOrThrow(this DynamicData.Kernel.Optional source, System.Func exceptionGenerator) + public static T ValueOrThrow(in this DynamicData.Kernel.Optional source, System.Func exceptionGenerator) where T : notnull { } } public static class OptionObservableExtensions @@ -2617,12 +2617,12 @@ namespace DynamicData.Kernel public override int GetHashCode() { } public override string? ToString() { } public static DynamicData.Kernel.Optional Create(T? value) { } - public static T? FromOptional(DynamicData.Kernel.Optional value) { } + public static T? FromOptional(in DynamicData.Kernel.Optional value) { } public static DynamicData.Kernel.Optional ToOptional(T? value) { } - public static T? op_Explicit(DynamicData.Kernel.Optional value) { } + public static T? op_Explicit(in DynamicData.Kernel.Optional value) { } public static DynamicData.Kernel.Optional op_Implicit(T? value) { } - public static bool operator !=(DynamicData.Kernel.Optional left, DynamicData.Kernel.Optional right) { } - public static bool operator ==(DynamicData.Kernel.Optional left, DynamicData.Kernel.Optional right) { } + public static bool operator !=(in DynamicData.Kernel.Optional left, in DynamicData.Kernel.Optional right) { } + public static bool operator ==(in DynamicData.Kernel.Optional left, in DynamicData.Kernel.Optional right) { } } } namespace DynamicData.List diff --git a/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs b/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs index d00596baa..4755cddbc 100644 --- a/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs +++ b/src/DynamicData.Tests/AggregationTests/AggregationFixture.cs @@ -89,8 +89,5 @@ public void CanHandleUpdatedItem() accumulator.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); } diff --git a/src/DynamicData.Tests/AggregationTests/AverageFixture.cs b/src/DynamicData.Tests/AggregationTests/AverageFixture.cs index 74fb16b87..400461a92 100644 --- a/src/DynamicData.Tests/AggregationTests/AverageFixture.cs +++ b/src/DynamicData.Tests/AggregationTests/AverageFixture.cs @@ -13,10 +13,7 @@ public class AverageFixture : IDisposable { private readonly SourceCache _source; - public AverageFixture() - { - _source = new SourceCache(p => p.Name); - } + public AverageFixture() => _source = new SourceCache(p => p.Name); [Fact] public void AddedItemsContributeToSum() @@ -178,10 +175,7 @@ public void AddedItemsContributeToSumNullableDecimal() accumulator.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InlineChangeReEvaluatesTotals() diff --git a/src/DynamicData.Tests/AggregationTests/MaxFixture.cs b/src/DynamicData.Tests/AggregationTests/MaxFixture.cs index 1b3a3ebf0..89f274619 100644 --- a/src/DynamicData.Tests/AggregationTests/MaxFixture.cs +++ b/src/DynamicData.Tests/AggregationTests/MaxFixture.cs @@ -13,10 +13,7 @@ public class MaxFixture : IDisposable { private readonly SourceCache _source; - public MaxFixture() - { - _source = new SourceCache(p => p.Name); - } + public MaxFixture() => _source = new SourceCache(p => p.Name); [Fact] public void AddItems() @@ -34,10 +31,7 @@ public void AddItems() accumulator.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InlineChangeReEvaluatesTotals() diff --git a/src/DynamicData.Tests/AggregationTests/MinFixture.cs b/src/DynamicData.Tests/AggregationTests/MinFixture.cs index fc6f4defb..168babdbd 100644 --- a/src/DynamicData.Tests/AggregationTests/MinFixture.cs +++ b/src/DynamicData.Tests/AggregationTests/MinFixture.cs @@ -13,10 +13,7 @@ public class MinFixture : IDisposable { private readonly SourceCache _source; - public MinFixture() - { - _source = new SourceCache(p => p.Name); - } + public MinFixture() => _source = new SourceCache(p => p.Name); [Fact] public void AddedItemsContributeToSum() @@ -34,10 +31,7 @@ public void AddedItemsContributeToSum() accumulator.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InlineChangeReEvaluatesTotals() diff --git a/src/DynamicData.Tests/AggregationTests/SumFixture.cs b/src/DynamicData.Tests/AggregationTests/SumFixture.cs index 0845b2c58..6fecbcabc 100644 --- a/src/DynamicData.Tests/AggregationTests/SumFixture.cs +++ b/src/DynamicData.Tests/AggregationTests/SumFixture.cs @@ -13,10 +13,7 @@ public class SumFixture : IDisposable { private readonly SourceCache _source; - public SumFixture() - { - _source = new SourceCache(p => p.Name); - } + public SumFixture() => _source = new SourceCache(p => p.Name); [Fact] public void AddedItemsContributeToSum() @@ -188,10 +185,7 @@ public void AddedItemsContributeToSumDecimalNullable() accumulator.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InlineChangeReEvaluatesTotals() diff --git a/src/DynamicData.Tests/AutoRefreshFilter.cs b/src/DynamicData.Tests/AutoRefreshFilter.cs index 5d110d60b..94226edb9 100644 --- a/src/DynamicData.Tests/AutoRefreshFilter.cs +++ b/src/DynamicData.Tests/AutoRefreshFilter.cs @@ -150,19 +150,13 @@ public void AutoRefreshWithObservablePredicate2() } } -public class Item : INotifyPropertyChanged +public class Item(string name) : INotifyPropertyChanged { - private string _name; - - public Item(string name) - { - Id = Guid.NewGuid(); - _name = name; - } + private string _name = name; public event PropertyChangedEventHandler? PropertyChanged; - public Guid Id { get; } + public Guid Id { get; } = Guid.NewGuid(); public string Name { diff --git a/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs b/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs index d33da4ca6..a706c4aea 100644 --- a/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs +++ b/src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs @@ -22,7 +22,7 @@ public class BindingListBindCacheSortedFixture : IDisposable private readonly IComparer _comparer = SortExpressionComparer.Ascending(p => p.Name); - private readonly RandomPersonGenerator _generator = new RandomPersonGenerator(); + private readonly RandomPersonGenerator _generator = new(); private readonly ISourceCache _source; diff --git a/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs index d1e9ff861..98d77cf62 100644 --- a/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs +++ b/src/DynamicData.Tests/Binding/BindingListToChangeSetFixture.cs @@ -149,9 +149,6 @@ public void InsertInto() private class TestBindingList : BindingList { - public void Reset() - { - OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); - } + public void Reset() => OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } } diff --git a/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs b/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs index c39d31b6c..e233c5c6a 100644 --- a/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs +++ b/src/DynamicData.Tests/Binding/DeeplyNestedNotifyPropertyChangedFixture.cs @@ -251,6 +251,8 @@ public void WithoutInitialValue() // [Fact] // [Trait("Manual run for benchmarking","xx")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Manual run for benchmarking")] private void StressIt() { var list = new SourceList(); @@ -266,9 +268,7 @@ private void StressIt() if (items.Length > 1 && items[1].Child is not null) { -#pragma warning disable CS8602 // Dereference of a possibly null reference. items[1].Child.Age = -1; -#pragma warning restore CS8602 // Dereference of a possibly null reference. } else { @@ -300,23 +300,17 @@ public string? Name /// The first value to compare. /// The second value to compare. /// true if the and parameters have the same value; otherwise, false. - public static bool operator ==(ClassA left, ClassA right) - { - return Equals(left, right); - } + public static bool operator ==(ClassA left, ClassA right) => Equals(left, right); /// Returns a value that indicates whether two objects have different values. /// The first value to compare. /// The second value to compare. /// true if and are not equal; otherwise, false. - public static bool operator !=(ClassA left, ClassA right) - { - return !Equals(left, right); - } + public static bool operator !=(ClassA left, ClassA right) => !Equals(left, right); public bool Equals(ClassA? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -331,7 +325,7 @@ public bool Equals(ClassA? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -357,10 +351,7 @@ public override int GetHashCode() } } - public override string ToString() - { - return $"ClassA: Name={Name}, {nameof(Child)}: {Child}"; - } + public override string ToString() => $"ClassA: Name={Name}, {nameof(Child)}: {Child}"; } public class ClassB : AbstractNotifyPropertyChanged, IEquatable @@ -377,23 +368,17 @@ public int Age /// The first value to compare. /// The second value to compare. /// true if the and parameters have the same value; otherwise, false. - public static bool operator ==(ClassB left, ClassB right) - { - return Equals(left, right); - } + public static bool operator ==(ClassB left, ClassB right) => Equals(left, right); /// Returns a value that indicates whether two objects have different values. /// The first value to compare. /// The second value to compare. /// true if and are not equal; otherwise, false. - public static bool operator !=(ClassB left, ClassB right) - { - return !Equals(left, right); - } + public static bool operator !=(ClassB left, ClassB right) => !Equals(left, right); public bool Equals(ClassB? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -408,7 +393,7 @@ public bool Equals(ClassB? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -426,15 +411,9 @@ public override bool Equals(object? obj) return Equals((ClassB)obj); } - public override int GetHashCode() - { - return _age; - } + public override int GetHashCode() => _age; - public override string ToString() - { - return $"{nameof(Age)}: {Age}"; - } + public override string ToString() => $"{nameof(Age)}: {Age}"; } public class ClassC : AbstractNotifyPropertyChanged diff --git a/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs b/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs index edc7f74aa..54e04a377 100644 --- a/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs +++ b/src/DynamicData.Tests/Binding/IObservableListBindCacheFixture.cs @@ -74,7 +74,7 @@ public void ListRecievesRefresh() person.Age = 60; - _listNotifications.Messages.Count().Should().Be(2); + _listNotifications.Messages.Count.Should().Be(2); _listNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh); } diff --git a/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs b/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs index fb9c1d9c5..9bc515fd0 100644 --- a/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs +++ b/src/DynamicData.Tests/Binding/IObservableListBindCacheSortedFixture.cs @@ -18,9 +18,9 @@ public class IObservableListBindCacheSortedFixture : IDisposable private static readonly IComparer _comparerNameDesc = SortExpressionComparer.Descending(p => p.Name); - private readonly BehaviorSubject> _comparer = new BehaviorSubject>(_comparerAgeAscThanNameAsc); + private readonly BehaviorSubject> _comparer = new(_comparerAgeAscThanNameAsc); - private readonly RandomPersonGenerator _generator = new RandomPersonGenerator(); + private readonly RandomPersonGenerator _generator = new(); private readonly IObservableList _list; @@ -82,6 +82,7 @@ public void Dispose() _sourceCacheNotifications.Dispose(); _listNotifications.Dispose(); _source.Dispose(); + _comparer.Dispose(); } [Fact] @@ -100,7 +101,7 @@ public void InitialBindWithExistingData() var listNotifications = list.Connect().AsAggregator(); // Assert - listNotifications.Messages.Count().Should().Be(1); + listNotifications.Messages.Count.Should().Be(1); listNotifications.Messages.First().First().Reason.Should().Be(ListChangeReason.AddRange); list.Items.Should().Equal(person1, person2); @@ -124,7 +125,7 @@ public void ListRecievesMoves() person3.Age = 1; // 1 ChangeSet with AddRange & 1 ChangeSet with Refresh & Move - _listNotifications.Messages.Count().Should().Be(2); + _listNotifications.Messages.Count.Should().Be(2); // Assert AddRange var addChangeSet = _listNotifications.Messages.First(); @@ -154,7 +155,7 @@ public void ListRecievesRefresh() person.Age = 60; - _listNotifications.Messages.Count().Should().Be(2); + _listNotifications.Messages.Count.Should().Be(2); _listNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh); } @@ -181,7 +182,7 @@ public void Reset() _list.Items.Should().Equal(sorted); - _listNotifications.Messages.Count().Should().Be(2); // Initial loading change set and a reset change due to a change over the reset threshold. + _listNotifications.Messages.Count.Should().Be(2); // Initial loading change set and a reset change due to a change over the reset threshold. _listNotifications.Messages[0].First().Reason.Should().Be(ListChangeReason.AddRange); // initial loading _listNotifications.Messages[1].Count.Should().Be(2); // Reset _listNotifications.Messages[1].First().Reason.Should().Be(ListChangeReason.Clear); // reset diff --git a/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs b/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs index 046b2ce36..06d13a7ee 100644 --- a/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs +++ b/src/DynamicData.Tests/Binding/IObservableListBindListFixture.cs @@ -168,7 +168,7 @@ public void ListRecievesRefresh() person.Age = 60; - _observableListNotifications.Messages.Count().Should().Be(2); + _observableListNotifications.Messages.Count.Should().Be(2); _observableListNotifications.Messages.Last().First().Reason.Should().Be(ListChangeReason.Refresh); } diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs index 0eead6df9..987d6a042 100644 --- a/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs +++ b/src/DynamicData.Tests/Binding/ObservableCollectionExtendedToChangeSetFixture.cs @@ -35,10 +35,7 @@ public void Add() _results.Data.Items.First().Should().Be(1); } - public void Dispose() - { - _results.Dispose(); - } + public void Dispose() => _results.Dispose(); [Fact] public void Duplicates() diff --git a/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs index b80bc9f55..6aacdc9ed 100644 --- a/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs +++ b/src/DynamicData.Tests/Binding/ObservableCollectionToChangeSetFixture.cs @@ -33,10 +33,7 @@ public void Add() _results.Data.Items.First().Should().Be(1); } - public void Dispose() - { - _results.Dispose(); - } + public void Dispose() => _results.Dispose(); [Fact] public void Duplicates() @@ -96,9 +93,6 @@ public void ResetFiresClearsAndAdds() private class TestObservableCollection : ObservableCollection { - public void Reset() - { - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - } + public void Reset() => OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs b/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs index 70ae7f149..a4f513eef 100644 --- a/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs +++ b/src/DynamicData.Tests/Binding/ReadOnlyObservableCollectionToChangeSetFixture.cs @@ -36,10 +36,7 @@ public void Add() _results.Data.Items.First().Should().Be(1); } - public void Dispose() - { - _results.Dispose(); - } + public void Dispose() => _results.Dispose(); [Fact] public void Duplicates() @@ -131,9 +128,6 @@ public void ResetFiresClearsAndAdds() private class TestObservableCollection : ObservableCollection { - public void Reset() - { - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - } + public void Reset() => OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); } } diff --git a/src/DynamicData.Tests/Cache/AndFixture.cs b/src/DynamicData.Tests/Cache/AndFixture.cs index 78b018580..9b447f20b 100644 --- a/src/DynamicData.Tests/Cache/AndFixture.cs +++ b/src/DynamicData.Tests/Cache/AndFixture.cs @@ -12,10 +12,7 @@ namespace DynamicData.Tests.Cache; public class AndFixture : AndFixtureBase { - protected override IObservable> CreateObservable() - { - return _source1.Connect().And(_source2.Connect()); - } + protected override IObservable> CreateObservable() => _source1.Connect().And(_source2.Connect()); } public class AndCollectionFixture : AndFixtureBase @@ -35,6 +32,7 @@ public abstract class AndFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected AndFixtureBase() { _source1 = new SourceCache(p => p.Name); diff --git a/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs b/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs index e84c43ac5..b3d36aa41 100644 --- a/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs +++ b/src/DynamicData.Tests/Cache/AutoRefreshFixture.cs @@ -106,17 +106,11 @@ public void MakeSelectMagicWorkWithObservable() } } - public class IntHolder : AbstractNotifyPropertyChanged + public class IntHolder(int value, string description) : AbstractNotifyPropertyChanged { - public string _description_; + public string _description_ = description; - public int _value; - - public IntHolder(int value, string description) - { - _value = value; - _description_ = description; - } + public int _value = value; public string Description { diff --git a/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs b/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs index 456876e89..239dba558 100644 --- a/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs +++ b/src/DynamicData.Tests/Cache/BatchIfWithTimeOutFixture.cs @@ -25,10 +25,7 @@ public BatchIfWithTimeoutFixture() _source = new SourceCache(p => p.Key); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InitialPause() diff --git a/src/DynamicData.Tests/Cache/DisposeManyFixture.cs b/src/DynamicData.Tests/Cache/DisposeManyFixture.cs index 83449b1da..b15be5a60 100644 --- a/src/DynamicData.Tests/Cache/DisposeManyFixture.cs +++ b/src/DynamicData.Tests/Cache/DisposeManyFixture.cs @@ -170,12 +170,9 @@ public void RemainingItemsAreDisposedAfterUnsubscription() items.All(item => item.IsDisposed).Should().BeTrue("Items remaining in the list should be disposed"); } - private class DisposableObject : IDisposable + private class DisposableObject(int id) : IDisposable { - public DisposableObject(int id) - => Id = id; - - public int Id { get; private set; } + public int Id { get; private set; } = id; public bool IsDisposed { get; private set; } diff --git a/src/DynamicData.Tests/Cache/EditDiffChangeSetFixture.cs b/src/DynamicData.Tests/Cache/EditDiffChangeSetFixture.cs index 88e12758a..a1acb56ff 100644 --- a/src/DynamicData.Tests/Cache/EditDiffChangeSetFixture.cs +++ b/src/DynamicData.Tests/Cache/EditDiffChangeSetFixture.cs @@ -159,16 +159,10 @@ public void Perf(int collectionSize, int updateSize, int maxItems) private static IEnumerable CreatePeople(int baseId, int count, string baseName) => Enumerable.Range(baseId, count).Select(i => CreatePerson(i, baseName + i)); - private class Person + private class Person(int id, string name) { - public Person(int id, string name) - { - Id = id; - Name = name; - } - - public int Id { get; } + public int Id { get; } = id; - public string Name { get; } + public string Name { get; } = name; } } diff --git a/src/DynamicData.Tests/Cache/EditDiffChangeSetOptionalFixture.cs b/src/DynamicData.Tests/Cache/EditDiffChangeSetOptionalFixture.cs index e814d0a7e..d87313af0 100644 --- a/src/DynamicData.Tests/Cache/EditDiffChangeSetOptionalFixture.cs +++ b/src/DynamicData.Tests/Cache/EditDiffChangeSetOptionalFixture.cs @@ -215,16 +215,10 @@ public bool Equals([DisallowNull] Person x, [DisallowNull] Person y) => public int GetHashCode([DisallowNull] Person obj) => throw new NotImplementedException(); } - private class Person + private class Person(int id, string name) { - public Person(int id, string name) - { - Id = id; - Name = name; - } - - public int Id { get; } + public int Id { get; } = id; - public string Name { get; } + public string Name { get; } = name; } } diff --git a/src/DynamicData.Tests/Cache/EnsureUniqueKeysFixture.cs b/src/DynamicData.Tests/Cache/EnsureUniqueKeysFixture.cs index 2dcf55b05..a12c914da 100644 --- a/src/DynamicData.Tests/Cache/EnsureUniqueKeysFixture.cs +++ b/src/DynamicData.Tests/Cache/EnsureUniqueKeysFixture.cs @@ -1,11 +1,12 @@ -using System.Linq; +using System; +using System.Linq; using DynamicData.Tests.Domain; using FluentAssertions; using Xunit; namespace DynamicData.Tests.Cache; -public class EnsureUniqueKeysFixture +public class EnsureUniqueKeysFixture: IDisposable { private readonly ISourceCache _source; private readonly ChangeSetAggregator _results; @@ -47,4 +48,10 @@ public void AddAndRemove() message1.Count.Should().Be(0); } + + public void Dispose() + { + _source.Dispose(); + _results.Dispose(); + } } diff --git a/src/DynamicData.Tests/Cache/ExceptFixture.cs b/src/DynamicData.Tests/Cache/ExceptFixture.cs index 0118b9407..17c4996e8 100644 --- a/src/DynamicData.Tests/Cache/ExceptFixture.cs +++ b/src/DynamicData.Tests/Cache/ExceptFixture.cs @@ -11,10 +11,7 @@ namespace DynamicData.Tests.Cache; public class ExceptFixture : ExceptFixtureBase { - protected override IObservable> CreateObservable() - { - return _targetSource.Connect().Except(_exceptSource.Connect()); - } + protected override IObservable> CreateObservable() => _targetSource.Connect().Except(_exceptSource.Connect()); } public class ExceptCollectionFixture : ExceptFixtureBase @@ -34,6 +31,7 @@ public abstract class ExceptFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected ExceptFixtureBase() { _targetSource = new SourceCache(p => p.Name); diff --git a/src/DynamicData.Tests/Cache/FilterOnObservableFixture.cs b/src/DynamicData.Tests/Cache/FilterOnObservableFixture.cs index 2e3b148d5..84b487055 100644 --- a/src/DynamicData.Tests/Cache/FilterOnObservableFixture.cs +++ b/src/DynamicData.Tests/Cache/FilterOnObservableFixture.cs @@ -183,7 +183,7 @@ public void ObservableFilterChangesCanBeBuffered() filterStats.Summary.Overall.Adds.Should().Be(MagicNumber); } - private static Person NewPerson(int n) => new Person("Name" + n, n); + private static Person NewPerson(int n) => new("Name" + n, n); private IEnumerable AddPeople(int count) { diff --git a/src/DynamicData.Tests/Cache/FilterOnPropertyFixture.cs b/src/DynamicData.Tests/Cache/FilterOnPropertyFixture.cs index 01ade3b18..0e7dc1fde 100644 --- a/src/DynamicData.Tests/Cache/FilterOnPropertyFixture.cs +++ b/src/DynamicData.Tests/Cache/FilterOnPropertyFixture.cs @@ -65,10 +65,7 @@ public void InitialValues() private class FilterPropertyStub : IDisposable { - public FilterPropertyStub() - { - Results = new ChangeSetAggregator(Source.Connect().FilterOnProperty(p => p.Age, p => p.Age > 18)); - } + public FilterPropertyStub() => Results = new ChangeSetAggregator(Source.Connect().FilterOnProperty(p => p.Age, p => p.Age > 18)); public ChangeSetAggregator Results { get; } diff --git a/src/DynamicData.Tests/Cache/ForEachChangeFixture.cs b/src/DynamicData.Tests/Cache/ForEachChangeFixture.cs index e6cd4b748..1da5de03a 100644 --- a/src/DynamicData.Tests/Cache/ForEachChangeFixture.cs +++ b/src/DynamicData.Tests/Cache/ForEachChangeFixture.cs @@ -13,15 +13,9 @@ public class ForEachChangeFixture : IDisposable { private readonly ISourceCache _source; - public ForEachChangeFixture() - { - _source = new SourceCache(p => p.Name); - } + public ForEachChangeFixture() => _source = new SourceCache(p => p.Name); - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void Test() diff --git a/src/DynamicData.Tests/Cache/FromAsyncFixture.cs b/src/DynamicData.Tests/Cache/FromAsyncFixture.cs index f65aca1f4..03f716d6d 100644 --- a/src/DynamicData.Tests/Cache/FromAsyncFixture.cs +++ b/src/DynamicData.Tests/Cache/FromAsyncFixture.cs @@ -16,10 +16,7 @@ namespace DynamicData.Tests.Cache; public class FromAsyncFixture { - public FromAsyncFixture() - { - Scheduler = new TestScheduler(); - } + public FromAsyncFixture() => Scheduler = new TestScheduler(); public TestScheduler Scheduler { get; } diff --git a/src/DynamicData.Tests/Cache/FullJoinFixture.cs b/src/DynamicData.Tests/Cache/FullJoinFixture.cs index bdda1c3bd..e290edcf1 100644 --- a/src/DynamicData.Tests/Cache/FullJoinFixture.cs +++ b/src/DynamicData.Tests/Cache/FullJoinFixture.cs @@ -176,28 +176,17 @@ public void UpdateRight() _result.Data.Items.All(dwm => dwm.MetaData != Optional.None).Should().BeTrue(); } - public class Device : IEquatable + public class Device(string name) : IEquatable { - public Device(string name) - { - Name = name; - } + public string Name { get; } = name; - public string Name { get; } + public static bool operator ==(Device left, Device right) => Equals(left, right); - public static bool operator ==(Device left, Device right) - { - return Equals(left, right); - } - - public static bool operator !=(Device left, Device right) - { - return !Equals(left, right); - } + public static bool operator !=(Device left, Device right) => !Equals(left, right); public bool Equals(Device? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -212,7 +201,7 @@ public bool Equals(Device? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -230,42 +219,24 @@ public override bool Equals(object? obj) return Equals((Device)obj); } - public override int GetHashCode() - { - return (Name is not null ? Name.GetHashCode() : 0); - } + public override int GetHashCode() => (Name is not null ? Name.GetHashCode() : 0); - public override string ToString() - { - return $"{Name}"; - } + public override string ToString() => $"{Name}"; } - public class DeviceMetaData : IEquatable + public class DeviceMetaData(string name, bool isAutoConnect = false) : IEquatable { - public DeviceMetaData(string name, bool isAutoConnect = false) - { - Name = name; - IsAutoConnect = isAutoConnect; - } + public bool IsAutoConnect { get; } = isAutoConnect; - public bool IsAutoConnect { get; } + public string Name { get; } = name; - public string Name { get; } + public static bool operator ==(DeviceMetaData left, DeviceMetaData right) => Equals(left, right); - public static bool operator ==(DeviceMetaData left, DeviceMetaData right) - { - return Equals(left, right); - } - - public static bool operator !=(DeviceMetaData left, DeviceMetaData right) - { - return !Equals(left, right); - } + public static bool operator !=(DeviceMetaData left, DeviceMetaData right) => !Equals(left, right); public bool Equals(DeviceMetaData? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -280,7 +251,7 @@ public bool Equals(DeviceMetaData? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -306,40 +277,24 @@ public override int GetHashCode() } } - public override string ToString() - { - return $"Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; - } + public override string ToString() => $"Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; } - public class DeviceWithMetadata : IEquatable + public class DeviceWithMetadata(string key, Optional device, Optional metaData) : IEquatable { - public DeviceWithMetadata(string key, Optional device, Optional metaData) - { - Key = key; - Device = device; - MetaData = metaData; - } + public Optional Device { get; set; } = device; - public Optional Device { get; set; } + public string Key { get; } = key; - public string Key { get; } + public Optional MetaData { get; } = metaData; - public Optional MetaData { get; } - - public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) - { - return Equals(left, right); - } + public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) => Equals(left, right); - public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) - { - return !Equals(left, right); - } + public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) => !Equals(left, right); public bool Equals(DeviceWithMetadata? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -354,7 +309,7 @@ public bool Equals(DeviceWithMetadata? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -372,15 +327,9 @@ public override bool Equals(object? obj) return Equals((DeviceWithMetadata)obj); } - public override int GetHashCode() - { - return (Key is not null ? Key.GetHashCode() : 0); - } + public override int GetHashCode() => (Key is not null ? Key.GetHashCode() : 0); - public override string ToString() - { - return $"{Key}: {Device} ({MetaData})"; - } + public override string ToString() => $"{Key}: {Device} ({MetaData})"; } private class Address diff --git a/src/DynamicData.Tests/Cache/FullJoinManyFixture.cs b/src/DynamicData.Tests/Cache/FullJoinManyFixture.cs index 14466f614..0a0c99c29 100644 --- a/src/DynamicData.Tests/Cache/FullJoinManyFixture.cs +++ b/src/DynamicData.Tests/Cache/FullJoinManyFixture.cs @@ -164,6 +164,7 @@ private void AssertDataIsCorrectlyFormed(Person[] allPeople) }); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private int CalculateParent(int index, int totalPeople) { if (index < 5) diff --git a/src/DynamicData.Tests/Cache/GroupFixture.cs b/src/DynamicData.Tests/Cache/GroupFixture.cs index 6782f95a1..c0139eed5 100644 --- a/src/DynamicData.Tests/Cache/GroupFixture.cs +++ b/src/DynamicData.Tests/Cache/GroupFixture.cs @@ -18,20 +18,17 @@ public class GroupFixture : IDisposable private ReadOnlyObservableCollection? _entries; - public GroupFixture() - { - _source = new SourceCache(p => p.Name); - } + public GroupFixture() => _source = new SourceCache(p => p.Name); [Fact] public void Kaboom() { SourceCache cache = new(x => x.Key); - List listWithDuplicates = new() - { + List listWithDuplicates = + [ new(1, "G1"), new(1, "G2"), - }; + ]; cache .Connect() .Group(x => x.Grouping) @@ -45,16 +42,10 @@ public void Kaboom() }); } - class Mytype + class Mytype(int key, string grouping) { - public Mytype(int key, string grouping) - { - Key = key; - Grouping = grouping; - } - - public int Key { get; set; } - public string Grouping { get; set; } + public int Key { get; set; } = key; + public string Grouping { get; set; } = grouping; public override string ToString() => $"{Key}, {Grouping}"; } @@ -81,7 +72,7 @@ public void AddItemAfterUpdateItemProcessAdd() { var subscriber = _source.Connect().Group(x => x.Name[0].ToString()).Transform(x => new GroupViewModel(x)).Bind(out _entries).Subscribe(); - _source.Edit(x => { x.AddOrUpdate(new Person("Adam", 1)); }); + _source.Edit(x => x.AddOrUpdate(new Person("Adam", 1))); var firstGroup = _entries.First(); firstGroup.Entries.Count.Should().Be(1); @@ -98,16 +89,13 @@ public void AddItemAfterUpdateItemProcessAdd() subscriber.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void FiresCompletedWhenDisposed() { var completed = false; - var subscriber = _source.Connect().Group(p => p.Age).Subscribe(updates => { }, () => { completed = true; }); + var subscriber = _source.Connect().Group(p => p.Age).Subscribe(updates => { }, () => completed = true); _source.Dispose(); subscriber.Dispose(); completed.Should().BeTrue(); @@ -196,7 +184,7 @@ public void FiresRemoveWhenEmptied() public void ReceivesUpdateWhenFeederIsInvoked() { var called = false; - var subscriber = _source.Connect().Group(p => p.Age).Subscribe(updates => { called = true; }); + var subscriber = _source.Connect().Group(p => p.Age).Subscribe(updates => called = true); _source.AddOrUpdate(new Person("Person1", 20)); subscriber.Dispose(); called.Should().BeTrue(); @@ -223,7 +211,7 @@ public void Remove() public void UpdateAnItemWillChangedThegroup() { var called = false; - var subscriber = _source.Connect().Group(p => p.Age).Subscribe(updates => { called = true; }); + var subscriber = _source.Connect().Group(p => p.Age).Subscribe(updates => called = true); _source.AddOrUpdate(new Person("Person1", 20)); _source.AddOrUpdate(new Person("Person1", 21)); subscriber.Dispose(); @@ -235,7 +223,7 @@ public void UpdateItemAfterAddItemProcessAdd() { var subscriber = _source.Connect().Group(x => x.Name[0].ToString()).Transform(x => new GroupViewModel(x)).Bind(out _entries).Subscribe(); - _source.Edit(x => { x.AddOrUpdate(new Person("Adam", 1)); }); + _source.Edit(x => x.AddOrUpdate(new Person("Adam", 1))); var firstGroup = _entries.First(); firstGroup.Entries.Count.Should().Be(1); @@ -256,31 +244,23 @@ public void UpdateItemAfterAddItemProcessAdd() public void UpdateNotPossible() { var called = false; - var subscriber = _source.Connect().Group(p => p.Age).Skip(1).Subscribe(updates => { called = true; }); + var subscriber = _source.Connect().Group(p => p.Age).Skip(1).Subscribe(updates => called = true); _source.AddOrUpdate(new Person("Person1", 20)); _source.AddOrUpdate(new Person("Person1", 20)); subscriber.Dispose(); called.Should().BeFalse(); } - public class GroupEntryViewModel + public class GroupEntryViewModel(Person person) { - public GroupEntryViewModel(Person person) - { - Person = person; - } - - public Person Person { get; } + public Person Person { get; } = person; } public class GroupViewModel { private readonly ReadOnlyObservableCollection _entries; - public GroupViewModel(IGroup person) - { - person.Cache.Connect().Transform(x => new GroupEntryViewModel(x)).Bind(out _entries).Subscribe(); - } + public GroupViewModel(IGroup person) => person?.Cache.Connect().Transform(x => new GroupEntryViewModel(x)).Bind(out _entries).Subscribe(); public ReadOnlyObservableCollection Entries => _entries; } diff --git a/src/DynamicData.Tests/Cache/IgnoreUpdateFixture.cs b/src/DynamicData.Tests/Cache/IgnoreUpdateFixture.cs index 17c4f6dec..7223a17af 100644 --- a/src/DynamicData.Tests/Cache/IgnoreUpdateFixture.cs +++ b/src/DynamicData.Tests/Cache/IgnoreUpdateFixture.cs @@ -23,6 +23,7 @@ public IgnoreUpdateFixture() public void Dispose() { _source.Dispose(); + _results.Dispose(); } [Fact] diff --git a/src/DynamicData.Tests/Cache/IncludeUpdateFixture.cs b/src/DynamicData.Tests/Cache/IncludeUpdateFixture.cs index 64908914b..5895a7e71 100644 --- a/src/DynamicData.Tests/Cache/IncludeUpdateFixture.cs +++ b/src/DynamicData.Tests/Cache/IncludeUpdateFixture.cs @@ -23,6 +23,7 @@ public IncludeUpdateFixture() public void Dispose() { _source.Dispose(); + _results.Dispose(); } [Fact] diff --git a/src/DynamicData.Tests/Cache/InnerJoinFixture.cs b/src/DynamicData.Tests/Cache/InnerJoinFixture.cs index 8553a6248..397c58029 100644 --- a/src/DynamicData.Tests/Cache/InnerJoinFixture.cs +++ b/src/DynamicData.Tests/Cache/InnerJoinFixture.cs @@ -206,28 +206,17 @@ public void MoreRight() } - public class Device : IEquatable + public class Device(string name) : IEquatable { - public Device(string name) - { - Name = name; - } + public string Name { get; } = name; - public string Name { get; } - - public static bool operator ==(Device left, Device right) - { - return Equals(left, right); - } + public static bool operator ==(Device left, Device right) => Equals(left, right); - public static bool operator !=(Device left, Device right) - { - return !Equals(left, right); - } + public static bool operator !=(Device left, Device right) => !Equals(left, right); public bool Equals(Device? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -242,7 +231,7 @@ public bool Equals(Device? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -260,84 +249,52 @@ public override bool Equals(object? obj) return Equals((Device)obj); } - public override int GetHashCode() - { - return (Name is not null ? Name.GetHashCode() : 0); - } + public override int GetHashCode() => (Name is not null ? Name.GetHashCode() : 0); - public override string ToString() - { - return $"{Name}"; - } + public override string ToString() => $"{Name}"; } - public class DeviceMetaData : IEquatable + public class DeviceMetaData(int key, string name, bool isAutoConnect = false) : IEquatable { - public DeviceMetaData(int key, string name, bool isAutoConnect = false) - { - Key = key; - Name = name; - IsAutoConnect = isAutoConnect; - } + public bool IsAutoConnect { get; } = isAutoConnect; + public int Key { get; } = key; + public string Name { get; } = name; - public bool IsAutoConnect { get; } - public int Key { get; } - public string Name { get; } - - public override string ToString() - { - return $"Key: {Key}. Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; - } + public override string ToString() => $"Key: {Key}. Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; public bool Equals(DeviceMetaData? other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return IsAutoConnect == other.IsAutoConnect && Key == other.Key && Name == other.Name; } public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((DeviceMetaData) obj); } - public override int GetHashCode() - { - return HashCode.Combine(IsAutoConnect, Key, Name); - } + public override int GetHashCode() => HashCode.Combine(IsAutoConnect, Key, Name); } - public class DeviceWithMetadata : IEquatable + public class DeviceWithMetadata((string leftKey, int rightKey) key, Device device, DeviceMetaData metaData) : IEquatable { - public DeviceWithMetadata((string leftKey, int rightKey) key, Device device, DeviceMetaData metaData) - { - Key = key; - Device = device; - MetaData = metaData; - } - - public Device Device { get; set; } + public Device Device { get; set; } = device; - public (string leftKey, int rightKey) Key { get; } + public (string leftKey, int rightKey) Key { get; } = key; - public DeviceMetaData MetaData { get; } + public DeviceMetaData MetaData { get; } = metaData; - public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) - { - return Equals(left, right); - } + public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) => Equals(left, right); - public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) - { - return !Equals(left, right); - } + public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) => !Equals(left, right); public bool Equals(DeviceWithMetadata? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -352,7 +309,7 @@ public bool Equals(DeviceWithMetadata? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -370,14 +327,8 @@ public override bool Equals(object? obj) return Equals((DeviceWithMetadata)obj); } - public override int GetHashCode() - { - return (Key is { } key ? key.GetHashCode() : 0); - } + public override int GetHashCode() => (Key is { } key ? key.GetHashCode() : 0); - public override string ToString() - { - return $"{Key}: {Device} ({MetaData})"; - } + public override string ToString() => $"{Key}: {Device} ({MetaData})"; } } diff --git a/src/DynamicData.Tests/Cache/InnerJoinManyFixture.cs b/src/DynamicData.Tests/Cache/InnerJoinManyFixture.cs index d590ae655..77f18ff2a 100644 --- a/src/DynamicData.Tests/Cache/InnerJoinManyFixture.cs +++ b/src/DynamicData.Tests/Cache/InnerJoinManyFixture.cs @@ -157,6 +157,7 @@ private void AssertDataIsCorrectlyFormed(Person[] allPeople, params string[] mis }); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private int CalculateParent(int index, int totalPeople) { if (index < 5) diff --git a/src/DynamicData.Tests/Cache/KeyValueCollectionEx.cs b/src/DynamicData.Tests/Cache/KeyValueCollectionEx.cs index 269629f0d..d8f46418e 100644 --- a/src/DynamicData.Tests/Cache/KeyValueCollectionEx.cs +++ b/src/DynamicData.Tests/Cache/KeyValueCollectionEx.cs @@ -6,8 +6,5 @@ namespace DynamicData.Tests.Cache; public static class KeyValueCollectionEx { public static IDictionary> Indexed(this IKeyValueCollection source) - where TKey : notnull - { - return source.Select((kv, idx) => new IndexedItem(kv.Value, kv.Key, idx)).ToDictionary(i => i.Key); - } + where TKey : notnull => source.Select((kv, idx) => new IndexedItem(kv.Value, kv.Key, idx)).ToDictionary(i => i.Key); } diff --git a/src/DynamicData.Tests/Cache/LeftJoinFixture.cs b/src/DynamicData.Tests/Cache/LeftJoinFixture.cs index 521cbdcdb..f2450f933 100644 --- a/src/DynamicData.Tests/Cache/LeftJoinFixture.cs +++ b/src/DynamicData.Tests/Cache/LeftJoinFixture.cs @@ -165,28 +165,17 @@ public void UpdateRight() _result.Data.Items.All(dwm => dwm.MetaData != Optional.None).Should().BeTrue(); } - public class Device : IEquatable + public class Device(string name) : IEquatable { - public Device(string name) - { - Name = name; - } + public string Name { get; } = name; - public string Name { get; } - - public static bool operator ==(Device left, Device right) - { - return Equals(left, right); - } + public static bool operator ==(Device left, Device right) => Equals(left, right); - public static bool operator !=(Device left, Device right) - { - return !Equals(left, right); - } + public static bool operator !=(Device left, Device right) => !Equals(left, right); public bool Equals(Device? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -201,7 +190,7 @@ public bool Equals(Device? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -219,42 +208,24 @@ public override bool Equals(object? obj) return Equals((Device)obj); } - public override int GetHashCode() - { - return (Name is not null ? Name.GetHashCode() : 0); - } + public override int GetHashCode() => (Name is not null ? Name.GetHashCode() : 0); - public override string ToString() - { - return $"{Name}"; - } + public override string ToString() => $"{Name}"; } - public class DeviceMetaData : IEquatable + public class DeviceMetaData(string name, bool isAutoConnect = false) : IEquatable { - public DeviceMetaData(string name, bool isAutoConnect = false) - { - Name = name; - IsAutoConnect = isAutoConnect; - } - - public bool IsAutoConnect { get; } + public bool IsAutoConnect { get; } = isAutoConnect; - public string Name { get; } + public string Name { get; } = name; - public static bool operator ==(DeviceMetaData left, DeviceMetaData right) - { - return Equals(left, right); - } + public static bool operator ==(DeviceMetaData left, DeviceMetaData right) => Equals(left, right); - public static bool operator !=(DeviceMetaData left, DeviceMetaData right) - { - return !Equals(left, right); - } + public static bool operator !=(DeviceMetaData left, DeviceMetaData right) => !Equals(left, right); public bool Equals(DeviceMetaData? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -269,7 +240,7 @@ public bool Equals(DeviceMetaData? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -295,37 +266,22 @@ public override int GetHashCode() } } - public override string ToString() - { - return $"Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; - } + public override string ToString() => $"Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; } - public class DeviceWithMetadata : IEquatable + public class DeviceWithMetadata(Device device, Optional metaData) : IEquatable { - public DeviceWithMetadata(Device device, Optional metaData) - { - Device = device; - MetaData = metaData; - } + public Device Device { get; } = device; - public Device Device { get; } + public Optional MetaData { get; } = metaData; - public Optional MetaData { get; } + public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) => Equals(left, right); - public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) - { - return Equals(left, right); - } - - public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) - { - return !Equals(left, right); - } + public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) => !Equals(left, right); public bool Equals(DeviceWithMetadata? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -340,7 +296,7 @@ public bool Equals(DeviceWithMetadata? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -361,9 +317,6 @@ public override int GetHashCode() } } - public override string ToString() - { - return $"{Device} ({MetaData})"; - } + public override string ToString() => $"{Device} ({MetaData})"; } } diff --git a/src/DynamicData.Tests/Cache/LeftJoinManyFixture.cs b/src/DynamicData.Tests/Cache/LeftJoinManyFixture.cs index 7b5838f88..1fc0748e9 100644 --- a/src/DynamicData.Tests/Cache/LeftJoinManyFixture.cs +++ b/src/DynamicData.Tests/Cache/LeftJoinManyFixture.cs @@ -53,7 +53,7 @@ public void AddLeftOnly() _result.Data.Count.Should().Be(10); _result.Data.Items.Select(pac => pac.Parent).Should().BeEquivalentTo(people); - _result.Data.Items.ForEach(pac => { pac.Count.Should().Be(0); }); + _result.Data.Items.ForEach(pac => pac.Count.Should().Be(0)); } [Fact] @@ -159,6 +159,7 @@ private void AssertDataIsCorrectlyFormed(Person[] expected, params string[] miss }); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private int CalculateParent(int index, int totalPeople) { if (index < 5) diff --git a/src/DynamicData.Tests/Cache/MergeChangeSetsFixture.cs b/src/DynamicData.Tests/Cache/MergeChangeSetsFixture.cs index e9bb54e0c..78b0befb0 100644 --- a/src/DynamicData.Tests/Cache/MergeChangeSetsFixture.cs +++ b/src/DynamicData.Tests/Cache/MergeChangeSetsFixture.cs @@ -849,10 +849,7 @@ public void ObservableObservableCompletesIfAndOnlyIfSourceAndAllChildrenComplete results.Completed.Should().Be(completeSource && completeChildren); } - public void Dispose() - { - _marketList.ForEach(m => (m as IDisposable)?.Dispose()); - } + public void Dispose() => _marketList.ForEach(m => (m as IDisposable)?.Dispose()); private Market Add(Market addThis) { diff --git a/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsFixture.cs b/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsFixture.cs index ca3396c0d..735e05552 100644 --- a/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsFixture.cs +++ b/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsFixture.cs @@ -37,10 +37,7 @@ public sealed class MergeManyCacheChangeSetsFixture : IDisposable private readonly ChangeSetAggregator _marketCacheResults; - public MergeManyCacheChangeSetsFixture() - { - _marketCacheResults = _marketCache.Connect().AsAggregator(); - } + public MergeManyCacheChangeSetsFixture() => _marketCacheResults = _marketCache.Connect().AsAggregator(); [Fact] public void NullChecks() diff --git a/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsSourceCompareFixture.cs b/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsSourceCompareFixture.cs index e3fd02908..1d0158bfa 100644 --- a/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsSourceCompareFixture.cs +++ b/src/DynamicData.Tests/Cache/MergeManyCacheChangeSetsSourceCompareFixture.cs @@ -37,10 +37,7 @@ public sealed class MergeManyCacheChangeSetsSourceCompareFixture : IDisposable private readonly ChangeSetAggregator _marketCacheResults; - public MergeManyCacheChangeSetsSourceCompareFixture() - { - _marketCacheResults = _marketCache.Connect().AsAggregator(); - } + public MergeManyCacheChangeSetsSourceCompareFixture() => _marketCacheResults = _marketCache.Connect().AsAggregator(); [Fact] public void NullChecks() diff --git a/src/DynamicData.Tests/Cache/MergeManyFixture.cs b/src/DynamicData.Tests/Cache/MergeManyFixture.cs index 8d7733d26..553bf452e 100644 --- a/src/DynamicData.Tests/Cache/MergeManyFixture.cs +++ b/src/DynamicData.Tests/Cache/MergeManyFixture.cs @@ -12,15 +12,9 @@ public class MergeManyFixture : IDisposable { private readonly SourceCache _source; - public MergeManyFixture() - { - _source = new SourceCache(p => p.Id); - } + public MergeManyFixture() => _source = new SourceCache(p => p.Id); - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void EverythingIsUnsubscribedWhenStreamIsDisposed() @@ -73,18 +67,13 @@ public void RemovedItemWillNotCauseInvocation() stream.Dispose(); } - private class ObjectWithObservable + private class ObjectWithObservable(int id) { private readonly ISubject _changed = new Subject(); private bool _value; - public ObjectWithObservable(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public IObservable Observable => _changed.AsObservable(); diff --git a/src/DynamicData.Tests/Cache/MergeManyItemsFixture.cs b/src/DynamicData.Tests/Cache/MergeManyItemsFixture.cs index 760580fbe..e2a6be748 100644 --- a/src/DynamicData.Tests/Cache/MergeManyItemsFixture.cs +++ b/src/DynamicData.Tests/Cache/MergeManyItemsFixture.cs @@ -12,15 +12,9 @@ public class MergeManyItemsFixture : IDisposable { private readonly ISourceCache _source; - public MergeManyItemsFixture() - { - _source = new SourceCache(p => p.Id); - } + public MergeManyItemsFixture() => _source = new SourceCache(p => p.Id); - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void EverythingIsUnsubscribedWhenStreamIsDisposed() @@ -85,18 +79,13 @@ public void RemovedItemWillNotCauseInvocation() stream.Dispose(); } - private class ObjectWithObservable + private class ObjectWithObservable(int id) { private readonly ISubject _changed = new Subject(); private bool _value; - public ObjectWithObservable(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public IObservable Observable => _changed.AsObservable(); diff --git a/src/DynamicData.Tests/Cache/MergeManyWithKeyOverloadFixture.cs b/src/DynamicData.Tests/Cache/MergeManyWithKeyOverloadFixture.cs index 82e4cf791..e6987e846 100644 --- a/src/DynamicData.Tests/Cache/MergeManyWithKeyOverloadFixture.cs +++ b/src/DynamicData.Tests/Cache/MergeManyWithKeyOverloadFixture.cs @@ -12,15 +12,9 @@ public class MergeManyWithKeyOverloadFixture : IDisposable { private readonly ISourceCache _source; - public MergeManyWithKeyOverloadFixture() - { - _source = new SourceCache(p => p.Id); - } + public MergeManyWithKeyOverloadFixture() => _source = new SourceCache(p => p.Id); - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void EverythingIsUnsubscribedWhenStreamIsDisposed() @@ -190,30 +184,19 @@ public void MergedStreamFailsWhenSourceFails() receivedError.Should().Be(expectedError); } - private class ObjectWithObservable + private class ObjectWithObservable(int id) { private readonly ISubject _changed = new Subject(); private bool _value; - public ObjectWithObservable(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public IObservable Observable => _changed.AsObservable(); - public void CompleteObservable() - { - _changed.OnCompleted(); - } + public void CompleteObservable() => _changed.OnCompleted(); - public void FailObservable(Exception ex) - { - _changed.OnError(ex); - } + public void FailObservable(Exception ex) => _changed.OnError(ex); public void InvokeObservable(bool value) { diff --git a/src/DynamicData.Tests/Cache/ObservableCachePreviewFixture.cs b/src/DynamicData.Tests/Cache/ObservableCachePreviewFixture.cs index e5c4bcbfc..801b03040 100644 --- a/src/DynamicData.Tests/Cache/ObservableCachePreviewFixture.cs +++ b/src/DynamicData.Tests/Cache/ObservableCachePreviewFixture.cs @@ -29,7 +29,7 @@ public void ChangesAreNotYetAppliedDuringPreview() _ => { Assert.True(_source.Count == 0); - Assert.True(_source.Items.Count() == 0); + Assert.True(_source.Items.Any() == false); }); // Trigger a change @@ -71,7 +71,7 @@ public void Dispose() public void NoChangesAllowedDuringPreview() { // On preview, try adding an arbitrary item - var d = _source.Preview().Subscribe(_ => { Assert.Throws(() => _source.AddOrUpdate(new Person("A", 1))); }); + var d = _source.Preview().Subscribe(_ => Assert.Throws(() => _source.AddOrUpdate(new Person("A", 1)))); // Trigger a change _source.AddOrUpdate(new Person("B", 2)); diff --git a/src/DynamicData.Tests/Cache/ObservableChangeSetFixture.cs b/src/DynamicData.Tests/Cache/ObservableChangeSetFixture.cs index 47e465168..4460dad3e 100644 --- a/src/DynamicData.Tests/Cache/ObservableChangeSetFixture.cs +++ b/src/DynamicData.Tests/Cache/ObservableChangeSetFixture.cs @@ -19,7 +19,8 @@ public class ObservableChangeSetFixture // [Fact] //Disabled due to test failing when run with a test runner. Run locally in isolation and it works [Description("See https://github.com/reactivemarbles/DynamicData/issues/383")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1030:Do not call ConfigureAwait in test method", Justification = "Without ConfigureAwait(false) we get a flakey test which always work when run in isolation but periodically fails when all tests are run.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Acceptable for test.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Disabled due to test failing when run with a test runner")] private async Task AsyncSubscriptionCanReceiveMultipleResults() { @@ -210,6 +211,7 @@ public void LoadsAndDisposeUsingDisposableAsync() isDisposed.Should().BeTrue(); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private void SubscribeAndAssert(IObservable> observableChangeset, bool expectsError = false, Action>? checkContentAction = null) where TKey : notnull where TObject : notnull diff --git a/src/DynamicData.Tests/Cache/OnItemFixture.cs b/src/DynamicData.Tests/Cache/OnItemFixture.cs index 52ec04bca..97aeebc75 100644 --- a/src/DynamicData.Tests/Cache/OnItemFixture.cs +++ b/src/DynamicData.Tests/Cache/OnItemFixture.cs @@ -91,8 +91,8 @@ public void ListAndCacheShouldHaveEquivalentBehaviour() { var source = new ObservableCollection { - new Item { Id = 1 }, - new Item { Id = 2 } + new() { Id = 1 }, + new() { Id = 2 } }; var list = source.ToObservableChangeSet() @@ -133,8 +133,8 @@ public class Proxy public class ProxyEqualityComparer : IEqualityComparer { - public bool Equals(Proxy x, Proxy y) => x.Item.Id == y.Item.Id && x.Active == y.Active; + public bool Equals(Proxy x, Proxy y) => x?.Item.Id == y?.Item.Id && x.Active == y.Active; - public int GetHashCode(Proxy obj) => HashCode.Combine(obj.Active, obj.Item); + public int GetHashCode(Proxy obj) => HashCode.Combine(obj?.Active, obj.Item); } } diff --git a/src/DynamicData.Tests/Cache/OrFixture.cs b/src/DynamicData.Tests/Cache/OrFixture.cs index 4b846d242..809d34dc2 100644 --- a/src/DynamicData.Tests/Cache/OrFixture.cs +++ b/src/DynamicData.Tests/Cache/OrFixture.cs @@ -12,10 +12,7 @@ namespace DynamicData.Tests.Cache; public class OrFixture : OrFixtureBase { - protected override IObservable> CreateObservable() - { - return _source1.Connect().Or(_source2.Connect()); - } + protected override IObservable> CreateObservable() => _source1.Connect().Or(_source2.Connect()); } public sealed class OrCollectionFixture : OrFixtureBase @@ -35,6 +32,7 @@ public abstract class OrFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected OrFixtureBase() { _source1 = new SourceCache(p => p.Name); diff --git a/src/DynamicData.Tests/Cache/PageFixture.cs b/src/DynamicData.Tests/Cache/PageFixture.cs index 0ecbb786e..8c31979d5 100644 --- a/src/DynamicData.Tests/Cache/PageFixture.cs +++ b/src/DynamicData.Tests/Cache/PageFixture.cs @@ -117,14 +117,8 @@ public void ReorderBelowThreshold() } [Fact] - public void ThrowsForNegativePage() - { - Assert.Throws(() => _pager.OnNext(new PageRequest(-1, 1))); - } + public void ThrowsForNegativePage() => Assert.Throws(() => _pager.OnNext(new PageRequest(-1, 1))); [Fact] - public void ThrowsForNegativeSizeParameters() - { - Assert.Throws(() => _pager.OnNext(new PageRequest(1, -1))); - } + public void ThrowsForNegativeSizeParameters() => Assert.Throws(() => _pager.OnNext(new PageRequest(1, -1))); } diff --git a/src/DynamicData.Tests/Cache/RefCountFixture.cs b/src/DynamicData.Tests/Cache/RefCountFixture.cs index 9d3c6aabd..14be2f16b 100644 --- a/src/DynamicData.Tests/Cache/RefCountFixture.cs +++ b/src/DynamicData.Tests/Cache/RefCountFixture.cs @@ -15,10 +15,7 @@ public class RefCountFixture : IDisposable { private readonly ISourceCache _source; - public RefCountFixture() - { - _source = new SourceCache(p => p.Key); - } + public RefCountFixture() => _source = new SourceCache(p => p.Key); [Fact] public void CanResubscribe() @@ -64,10 +61,7 @@ public void ChainIsInvokedOnceForMultipleSubscribers() disposals.Should().Be(1); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); // This test is probabilistic, it could be cool to be able to prove RefCount's thread-safety // more accurately but I don't think that there is an easy way to do this. diff --git a/src/DynamicData.Tests/Cache/RightJoinFixture.cs b/src/DynamicData.Tests/Cache/RightJoinFixture.cs index 07052164d..8a8e63dcb 100644 --- a/src/DynamicData.Tests/Cache/RightJoinFixture.cs +++ b/src/DynamicData.Tests/Cache/RightJoinFixture.cs @@ -218,28 +218,17 @@ public void MoreRight() - public class Device : IEquatable + public class Device(string name) : IEquatable { - public Device(string name) - { - Name = name; - } + public string Name { get; } = name; - public string Name { get; } - - public static bool operator ==(Device left, Device right) - { - return Equals(left, right); - } + public static bool operator ==(Device left, Device right) => Equals(left, right); - public static bool operator !=(Device left, Device right) - { - return !Equals(left, right); - } + public static bool operator !=(Device left, Device right) => !Equals(left, right); public bool Equals(Device? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -254,7 +243,7 @@ public bool Equals(Device? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -272,84 +261,52 @@ public override bool Equals(object? obj) return Equals((Device)obj); } - public override int GetHashCode() - { - return (Name is not null ? Name.GetHashCode() : 0); - } + public override int GetHashCode() => (Name is not null ? Name.GetHashCode() : 0); - public override string ToString() - { - return $"{Name}"; - } + public override string ToString() => $"{Name}"; } - public class DeviceMetaData : IEquatable + public class DeviceMetaData(int key, string name, bool isAutoConnect = false) : IEquatable { - public DeviceMetaData(int key, string name, bool isAutoConnect = false) - { - Key = key; - Name = name; - IsAutoConnect = isAutoConnect; - } + public bool IsAutoConnect { get; } = isAutoConnect; + public int Key { get; } = key; + public string Name { get; } = name; - public bool IsAutoConnect { get; } - public int Key { get; } - public string Name { get; } - - public override string ToString() - { - return $"Key: {Key}. Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; - } + public override string ToString() => $"Key: {Key}. Metadata: {Name}. IsAutoConnect = {IsAutoConnect}"; public bool Equals(DeviceMetaData? other) { - if (ReferenceEquals(null, other)) return false; + if (other is null) return false; if (ReferenceEquals(this, other)) return true; return IsAutoConnect == other.IsAutoConnect && Key == other.Key && Name == other.Name; } public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; return Equals((DeviceMetaData) obj); } - public override int GetHashCode() - { - return HashCode.Combine(IsAutoConnect, Key, Name); - } + public override int GetHashCode() => HashCode.Combine(IsAutoConnect, Key, Name); } - public class DeviceWithMetadata : IEquatable + public class DeviceWithMetadata(int key, Optional device, DeviceMetaData metaData) : IEquatable { - public DeviceWithMetadata(int key, Optional device, DeviceMetaData metaData) - { - Key = key; - Device = device; - MetaData = metaData; - } - - public Optional Device { get; } + public Optional Device { get; } = device; - public int Key { get; } + public int Key { get; } = key; - public DeviceMetaData MetaData { get; } + public DeviceMetaData MetaData { get; } = metaData; - public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) - { - return Equals(left, right); - } + public static bool operator ==(DeviceWithMetadata left, DeviceWithMetadata right) => Equals(left, right); - public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) - { - return !Equals(left, right); - } + public static bool operator !=(DeviceWithMetadata left, DeviceWithMetadata right) => !Equals(left, right); public bool Equals(DeviceWithMetadata? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -364,7 +321,7 @@ public bool Equals(DeviceWithMetadata? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -382,14 +339,8 @@ public override bool Equals(object? obj) return Equals((DeviceWithMetadata)obj); } - public override int GetHashCode() - { - return Key; - } + public override int GetHashCode() => Key; - public override string ToString() - { - return $"{Key}: {Device} ({MetaData})"; - } + public override string ToString() => $"{Key}: {Device} ({MetaData})"; } } diff --git a/src/DynamicData.Tests/Cache/RightJoinManyFixture.cs b/src/DynamicData.Tests/Cache/RightJoinManyFixture.cs index 73df5b833..6f3c63bcd 100644 --- a/src/DynamicData.Tests/Cache/RightJoinManyFixture.cs +++ b/src/DynamicData.Tests/Cache/RightJoinManyFixture.cs @@ -158,6 +158,7 @@ private void AssertDataIsCorrectlyFormed(Person[] allPeople, params string[] mis }); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private int CalculateParent(int index, int totalPeople) { if (index < 5) diff --git a/src/DynamicData.Tests/Cache/SizeLimitFixture.cs b/src/DynamicData.Tests/Cache/SizeLimitFixture.cs index 06b2dcb9c..2de5c165c 100644 --- a/src/DynamicData.Tests/Cache/SizeLimitFixture.cs +++ b/src/DynamicData.Tests/Cache/SizeLimitFixture.cs @@ -128,9 +128,7 @@ public void OnCompleteIsInvokedWhenSourceIsDisposed() } [Fact] - public void ThrowsIfSizeLimitIsZero() - { + public void ThrowsIfSizeLimitIsZero() => // Initialise(); Assert.Throws(() => new SourceCache(p => p.Key).LimitSizeTo(0)); - } } diff --git a/src/DynamicData.Tests/Cache/SortFixture.cs b/src/DynamicData.Tests/Cache/SortFixture.cs index e867755ae..e80b98ef5 100644 --- a/src/DynamicData.Tests/Cache/SortFixture.cs +++ b/src/DynamicData.Tests/Cache/SortFixture.cs @@ -22,7 +22,7 @@ public class SortFixtureWithReorder : IDisposable { private readonly IComparer _comparer; - private readonly RandomPersonGenerator _generator = new RandomPersonGenerator(); + private readonly RandomPersonGenerator _generator = new(); private readonly SortedChangeSetAggregator _results; @@ -481,69 +481,35 @@ public void UpdateMiddle() list.Should().BeEquivalentTo(sortedResult); } - public class Data + public class Data(int id, string value) { - public Data(int id, string value) - { - Id = id; - Value = value; - } - - public int Id { get; } + public int Id { get; } = id; - public string Value { get; } + public string Value { get; } = value; } - public class TestString : IEquatable + public class TestString(string name) : IEquatable { - private readonly string _name; - - public TestString(string name) - { - _name = name; - } + private readonly string _name = name; - public static implicit operator TestString(string source) - { - return new TestString(source); - } + public static implicit operator TestString(string source) => new(source); - public static implicit operator string(TestString source) - { - return source._name; - } + public static implicit operator string(TestString source) => source?._name!; - public bool Equals(TestString? other) - { - return StringComparer.OrdinalIgnoreCase.Equals(_name, other?._name); - } + public bool Equals(TestString? other) => StringComparer.OrdinalIgnoreCase.Equals(_name, other?._name); - public override bool Equals(object? obj) - { - return obj is TestString value && Equals(value); - } + public override bool Equals(object? obj) => obj is TestString value && Equals(value); - public override int GetHashCode() - { - return StringComparer.OrdinalIgnoreCase.GetHashCode(_name); - } + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(_name); } - public class ViewModel + public class ViewModel(string name) { - public ViewModel(string name) - { - Name = name; - } - - public string Name { get; } + public string Name { get; } = name; public class Comparer : IComparer { - public int Compare(ViewModel? x, ViewModel? y) - { - return StringComparer.OrdinalIgnoreCase.Compare(x?.Name, y?.Name); - } + public int Compare(ViewModel? x, ViewModel? y) => StringComparer.OrdinalIgnoreCase.Compare(x?.Name, y?.Name); } } } @@ -552,7 +518,7 @@ public class SortFixture : IDisposable { private readonly IComparer _comparer; - private readonly RandomPersonGenerator _generator = new RandomPersonGenerator(); + private readonly RandomPersonGenerator _generator = new(); private readonly SortedChangeSetAggregator _results; @@ -1041,69 +1007,35 @@ public void UpdateMiddle() list.Should().BeEquivalentTo(sortedResult); } - public class Data + public class Data(int id, string value) { - public Data(int id, string value) - { - Id = id; - Value = value; - } - - public int Id { get; } + public int Id { get; } = id; - public string Value { get; } + public string Value { get; } = value; } - public class TestString : IEquatable + public class TestString(string name) : IEquatable { - private readonly string _name; - - public TestString(string name) - { - _name = name; - } + private readonly string _name = name; - public static implicit operator TestString(string source) - { - return new TestString(source); - } + public static implicit operator TestString(string source) => new(source); - public static implicit operator string(TestString source) - { - return source._name; - } + public static implicit operator string(TestString source) => source?._name!; - public bool Equals(TestString? other) - { - return StringComparer.OrdinalIgnoreCase.Equals(_name, other?._name); - } + public bool Equals(TestString? other) => StringComparer.OrdinalIgnoreCase.Equals(_name, other?._name); - public override bool Equals(object? obj) - { - return obj is TestString testString && Equals(testString); - } + public override bool Equals(object? obj) => obj is TestString testString && Equals(testString); - public override int GetHashCode() - { - return StringComparer.OrdinalIgnoreCase.GetHashCode(_name); - } + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(_name); } - public class ViewModel + public class ViewModel(string name) { - public ViewModel(string name) - { - this.Name = name; - } - - public string Name { get; set; } + public string Name { get; set; } = name; public class Comparer : IComparer { - public int Compare(ViewModel? x, ViewModel? y) - { - return StringComparer.OrdinalIgnoreCase.Compare(x?.Name, y?.Name); - } + public int Compare(ViewModel? x, ViewModel? y) => StringComparer.OrdinalIgnoreCase.Compare(x?.Name, y?.Name); } } } diff --git a/src/DynamicData.Tests/Cache/SortObservableFixtureFixture.cs b/src/DynamicData.Tests/Cache/SortObservableFixtureFixture.cs index 94c772d0f..6175a0f5c 100644 --- a/src/DynamicData.Tests/Cache/SortObservableFixtureFixture.cs +++ b/src/DynamicData.Tests/Cache/SortObservableFixtureFixture.cs @@ -18,6 +18,7 @@ public class SortObservableFixture : IDisposable private readonly SortExpressionComparer _comparer; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "By Design.")] private readonly BehaviorSubject> _comparerObservable; private readonly RandomPersonGenerator _generator = new(); diff --git a/src/DynamicData.Tests/Cache/SubscribeManyFixture.cs b/src/DynamicData.Tests/Cache/SubscribeManyFixture.cs index f7ea4270d..7e8423ebe 100644 --- a/src/DynamicData.Tests/Cache/SubscribeManyFixture.cs +++ b/src/DynamicData.Tests/Cache/SubscribeManyFixture.cs @@ -75,25 +75,14 @@ public void UpdateUnsubscribesPrevious() _results.Messages[1].First().Previous.Value.IsSubscribed.Should().Be(false, "Previous should not be subscribed"); } - private class SubscribeableObject + private class SubscribeableObject(int id) { - public SubscribeableObject(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public bool IsSubscribed { get; private set; } - public void Subscribe() - { - IsSubscribed = true; - } + public void Subscribe() => IsSubscribed = true; - public void UnSubscribe() - { - IsSubscribed = false; - } + public void UnSubscribe() => IsSubscribed = false; } } diff --git a/src/DynamicData.Tests/Cache/ToObservableOptionalFixture.cs b/src/DynamicData.Tests/Cache/ToObservableOptionalFixture.cs index 509e93a58..1d041df21 100644 --- a/src/DynamicData.Tests/Cache/ToObservableOptionalFixture.cs +++ b/src/DynamicData.Tests/Cache/ToObservableOptionalFixture.cs @@ -22,10 +22,7 @@ public class ToObservableOptionalFixture : IDisposable private readonly ISourceCache _source = new SourceCache(kvp => kvp.Key); private readonly ChangeSetAggregator _results; - public ToObservableOptionalFixture() - { - _results = _source.Connect().AsAggregator(); - } + public ToObservableOptionalFixture() => _results = _source.Connect().AsAggregator(); public void Dispose() { @@ -34,10 +31,7 @@ public void Dispose() } [Fact] - public void NullChecks() - { - Assert.Throws(() => ObservableCacheEx.ToObservableOptional(null!, string.Empty)); - } + public void NullChecks() => Assert.Throws(() => ObservableCacheEx.ToObservableOptional(null!, string.Empty)); [Fact] public void AddingToCacheEmitsOptionalSome() @@ -290,31 +284,25 @@ public void ObservableFailsIfAndOnlyIfSourceFails(bool failSource) receivedError.Should().Be(failSource ? testException : default); } - private static KeyValuePair Create(string key, string value) => new KeyValuePair(key, value); + private static KeyValuePair Create(string key, string value) => new(key, value); - private class KeyValueCompare : IEqualityComparer + private class KeyValueCompare(IEqualityComparer stringComparer) : IEqualityComparer { - private IEqualityComparer _stringComparer; - public KeyValueCompare(IEqualityComparer stringComparer) => _stringComparer = stringComparer; + private IEqualityComparer _stringComparer = stringComparer; + public bool Equals([DisallowNull] KeyValuePair x, [DisallowNull] KeyValuePair y) => _stringComparer.Equals(x.Value, y.Value); public int GetHashCode([DisallowNull] KeyValuePair obj) => throw new NotImplementedException(); } - private static KeyValueCompare CaseInsensitiveComparer => new KeyValueCompare(StringComparer.OrdinalIgnoreCase); + private static KeyValueCompare CaseInsensitiveComparer => new(StringComparer.OrdinalIgnoreCase); - private static KeyValueCompare CaseSensitiveComparer => new KeyValueCompare(StringComparer.Ordinal); + private static KeyValueCompare CaseSensitiveComparer => new(StringComparer.Ordinal); - private class KeyValuePair + private class KeyValuePair(string key, string value) { - public KeyValuePair(string key, string value) - { - Key = key; - Value = value; - } - - public string Key { get; } + public string Key { get; } = key; - public string Value { get; } + public string Value { get; } = value; } } diff --git a/src/DynamicData.Tests/Cache/TransformFixture.cs b/src/DynamicData.Tests/Cache/TransformFixture.cs index 5371155ae..89fa079b4 100644 --- a/src/DynamicData.Tests/Cache/TransformFixture.cs +++ b/src/DynamicData.Tests/Cache/TransformFixture.cs @@ -153,20 +153,11 @@ public void Update() private class TransformStub : IDisposable { - public TransformStub() - { - Results = new ChangeSetAggregator(Source.Connect().Transform(TransformFactory)); - } + public TransformStub() => Results = new ChangeSetAggregator(Source.Connect().Transform(TransformFactory)); - public TransformStub(IObservable retransformer) - { - Results = new ChangeSetAggregator(Source.Connect().Transform(TransformFactory, retransformer)); - } + public TransformStub(IObservable retransformer) => Results = new ChangeSetAggregator(Source.Connect().Transform(TransformFactory, retransformer)); - public TransformStub(IObservable> retransformer) - { - Results = new ChangeSetAggregator(Source.Connect().Transform(TransformFactory, retransformer)); - } + public TransformStub(IObservable> retransformer) => Results = new ChangeSetAggregator(Source.Connect().Transform(TransformFactory, retransformer)); public ChangeSetAggregator Results { get; } diff --git a/src/DynamicData.Tests/Cache/TransformFixtureParallel.cs b/src/DynamicData.Tests/Cache/TransformFixtureParallel.cs index 52b908b6c..1f61a7d7b 100644 --- a/src/DynamicData.Tests/Cache/TransformFixtureParallel.cs +++ b/src/DynamicData.Tests/Cache/TransformFixtureParallel.cs @@ -106,6 +106,7 @@ public void SameKeyChanges() var lastTransformed = _transformFactory(people.Last()); var onlyItemInCache = _results.Data.Items.First(); + // TODO: This is not producing consitent results, the lastTransformed item should be equal to the onlyItemInCache onlyItemInCache.Should().Be(lastTransformed, "Incorrect transform result"); } diff --git a/src/DynamicData.Tests/Cache/TransformSafeAsyncFixture.cs b/src/DynamicData.Tests/Cache/TransformSafeAsyncFixture.cs index 30a816b3b..415c9a65b 100644 --- a/src/DynamicData.Tests/Cache/TransformSafeAsyncFixture.cs +++ b/src/DynamicData.Tests/Cache/TransformSafeAsyncFixture.cs @@ -279,9 +279,6 @@ public void Dispose() Results.Dispose(); } - private void ErrorHandler(Error error) - { - HandledErrors.Add(error); - } + private void ErrorHandler(Error error) => HandledErrors.Add(error); } } diff --git a/src/DynamicData.Tests/Cache/TransformTreeFixture.cs b/src/DynamicData.Tests/Cache/TransformTreeFixture.cs index 148dea4f9..e24bb4fbb 100644 --- a/src/DynamicData.Tests/Cache/TransformTreeFixture.cs +++ b/src/DynamicData.Tests/Cache/TransformTreeFixture.cs @@ -78,7 +78,7 @@ public void AddMissingParent() [Fact] public void BuildTreeFromMixedData() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); _result.Count.Should().Be(2); var firstNode = _result.Items.First(); @@ -91,7 +91,7 @@ public void BuildTreeFromMixedData() [Fact] public void ChangeParent() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); _sourceCache.AddOrUpdate( new EmployeeDto(4) @@ -117,12 +117,13 @@ public void Dispose() { _sourceCache.Dispose(); _result.Dispose(); + _filter.Dispose(); } [Fact] public void RemoveAChildNodeWillPushOrphansUpTheHierachy() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); _sourceCache.Remove(4); //we expect the children of node 4 to be pushed up become new roots @@ -135,7 +136,7 @@ public void RemoveAChildNodeWillPushOrphansUpTheHierachy() [Fact] public void RemoveARootNodeWillPushOrphansUpTheHierachy() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); _sourceCache.Remove(1); //we expect the original children nodes to be pushed up become new roots @@ -145,7 +146,7 @@ public void RemoveARootNodeWillPushOrphansUpTheHierachy() [Fact] public void UpdateAParentNode() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); var changed = new EmployeeDto(1) { @@ -164,7 +165,7 @@ public void UpdateAParentNode() [Fact] public void UpdateChildNode() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); var changed = new EmployeeDto(2) { @@ -185,7 +186,7 @@ public void UpdateChildNode() [Fact] public void UseCustomFilter() { - _sourceCache.AddOrUpdate(CreateEmployees()); + _sourceCache.AddOrUpdate(TransformTreeFixture.CreateEmployees()); _result.Count.Should().Be(2); @@ -202,7 +203,7 @@ public void UseCustomFilter() _result.Count.Should().Be(2); } - private IEnumerable CreateEmployees() + private static IEnumerable CreateEmployees() { yield return new EmployeeDto(1) { @@ -253,32 +254,21 @@ private IEnumerable CreateEmployees() }; } - public class EmployeeDto : IEquatable + public class EmployeeDto(int id) : IEquatable { - public EmployeeDto(int id) - { - Id = id; - } - public int BossId { get; set; } - public int Id { get; set; } + public int Id { get; set; } = id; public string? Name { get; set; } - public static bool operator ==(EmployeeDto left, EmployeeDto right) - { - return Equals(left, right); - } + public static bool operator ==(EmployeeDto left, EmployeeDto right) => Equals(left, right); - public static bool operator !=(EmployeeDto left, EmployeeDto right) - { - return !Equals(left, right); - } + public static bool operator !=(EmployeeDto left, EmployeeDto right) => !Equals(left, right); public bool Equals(EmployeeDto? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -293,7 +283,7 @@ public bool Equals(EmployeeDto? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -311,14 +301,8 @@ public override bool Equals(object? obj) return Equals((EmployeeDto)obj); } - public override int GetHashCode() - { - return Id; - } + public override int GetHashCode() => Id; - public override string ToString() - { - return $"Name: {Name}, Id: {Id}, BossId: {BossId}"; - } + public override string ToString() => $"Name: {Name}, Id: {Id}, BossId: {BossId}"; } } diff --git a/src/DynamicData.Tests/Cache/TransformTreeWithRefreshFixture.cs b/src/DynamicData.Tests/Cache/TransformTreeWithRefreshFixture.cs index 697dde971..68748a69b 100644 --- a/src/DynamicData.Tests/Cache/TransformTreeWithRefreshFixture.cs +++ b/src/DynamicData.Tests/Cache/TransformTreeWithRefreshFixture.cs @@ -96,6 +96,7 @@ public void UpdateTreeWhenParentIdOfRootItemChangedToNonExistingId() node1.Value.IsRoot.Should().BeTrue(); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private IEnumerable CreateEmployees() { yield return new EmployeeDto(1) @@ -147,24 +148,19 @@ private IEnumerable CreateEmployees() }; } - private class EmployeeDto : AbstractNotifyPropertyChanged, IEquatable + private class EmployeeDto(int id) : AbstractNotifyPropertyChanged, IEquatable { private int _bossId; private string? _name; - public EmployeeDto(int id) - { - Id = id; - } - public int BossId { get => _bossId; set => SetAndRaise(ref _bossId, value); } - public int Id { get; } + public int Id { get; } = id; public string? Name { @@ -172,19 +168,13 @@ public string? Name set => SetAndRaise(ref _name, value); } - public static bool operator ==(EmployeeDto left, EmployeeDto right) - { - return Equals(left, right); - } + public static bool operator ==(EmployeeDto left, EmployeeDto right) => Equals(left, right); - public static bool operator !=(EmployeeDto left, EmployeeDto right) - { - return !Equals(left, right); - } + public static bool operator !=(EmployeeDto left, EmployeeDto right) => !Equals(left, right); public bool Equals(EmployeeDto? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -199,7 +189,7 @@ public bool Equals(EmployeeDto? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -217,14 +207,8 @@ public override bool Equals(object? obj) return Equals((EmployeeDto)obj); } - public override int GetHashCode() - { - return Id; - } + public override int GetHashCode() => Id; - public override string ToString() - { - return $"Name: {Name}, Id: {Id}, BossId: {BossId}"; - } + public override string ToString() => $"Name: {Name}, Id: {Id}, BossId: {BossId}"; } } diff --git a/src/DynamicData.Tests/Cache/TransformWithInlineUpdateFixture.cs b/src/DynamicData.Tests/Cache/TransformWithInlineUpdateFixture.cs index cb32054c9..170ffadf2 100644 --- a/src/DynamicData.Tests/Cache/TransformWithInlineUpdateFixture.cs +++ b/src/DynamicData.Tests/Cache/TransformWithInlineUpdateFixture.cs @@ -78,10 +78,7 @@ public void Remove() private class TransformWithInlineUpdateFixtureStub : IDisposable { - public TransformWithInlineUpdateFixtureStub() - { - Results = new ChangeSetAggregator(Source.Connect().TransformWithInlineUpdate(TransformFactory, UpdateAction)); - } + public TransformWithInlineUpdateFixtureStub() => Results = new ChangeSetAggregator(Source.Connect().TransformWithInlineUpdate(TransformFactory, UpdateAction)); public ChangeSetAggregator Results { get; } diff --git a/src/DynamicData.Tests/Cache/TrueForAllFixture.cs b/src/DynamicData.Tests/Cache/TrueForAllFixture.cs index 1ab1fa0fb..f9dece32b 100644 --- a/src/DynamicData.Tests/Cache/TrueForAllFixture.cs +++ b/src/DynamicData.Tests/Cache/TrueForAllFixture.cs @@ -20,10 +20,7 @@ public TrueForAllFixture() _observable = _source.Connect().TrueForAll(o => o.Observable.StartWith(o.Value), (obj, invoked) => invoked); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InitialItemReturnsFalseWhenObservableHasNoValue() @@ -93,16 +90,11 @@ public void MultipleValuesReturnTrue() subscribed.Dispose(); } - private class ObjectWithObservable + private class ObjectWithObservable(int id) { private readonly ISubject _changed = new Subject(); - public ObjectWithObservable(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public IObservable Observable => _changed; diff --git a/src/DynamicData.Tests/Cache/TrueForAnyFixture.cs b/src/DynamicData.Tests/Cache/TrueForAnyFixture.cs index 3ca670318..04fc77ca1 100644 --- a/src/DynamicData.Tests/Cache/TrueForAnyFixture.cs +++ b/src/DynamicData.Tests/Cache/TrueForAnyFixture.cs @@ -20,10 +20,7 @@ public TrueForAnyFixture() _observable = _source.Connect().TrueForAny(o => o.Observable.StartWith(o.Value), o => o == true); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void InitialItemReturnsFalseWhenObservaleHasNoValue() @@ -80,16 +77,11 @@ public void MultipleValuesReturnTrue() subscribed.Dispose(); } - private class ObjectWithObservable + private class ObjectWithObservable(int id) { private readonly ISubject _changed = new Subject(); - public ObjectWithObservable(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public IObservable Observable => _changed; diff --git a/src/DynamicData.Tests/Cache/WatchFixture.cs b/src/DynamicData.Tests/Cache/WatchFixture.cs index 3d44f17c1..9064cd28e 100644 --- a/src/DynamicData.Tests/Cache/WatchFixture.cs +++ b/src/DynamicData.Tests/Cache/WatchFixture.cs @@ -68,20 +68,12 @@ public void UpdateWillCallDispose() _results.Messages[1].First().Previous.Value.IsDisposed.Should().Be(true, "Previous should be disposed"); } - private class DisposableObject : IDisposable + private class DisposableObject(int id) : IDisposable { - public DisposableObject(int id) - { - Id = id; - } - - public int Id { get; private set; } + public int Id { get; private set; } = id; public bool IsDisposed { get; private set; } - public void Dispose() - { - IsDisposed = true; - } + public void Dispose() => IsDisposed = true; } } diff --git a/src/DynamicData.Tests/Cache/WatcherFixture.cs b/src/DynamicData.Tests/Cache/WatcherFixture.cs index 447f970a3..8fde89096 100644 --- a/src/DynamicData.Tests/Cache/WatcherFixture.cs +++ b/src/DynamicData.Tests/Cache/WatcherFixture.cs @@ -65,6 +65,9 @@ public void AddNew() public void Dispose() { _cleanUp.Dispose(); + _results.Dispose(); + _source.Dispose(); + _watcher.Dispose(); } [Fact] diff --git a/src/DynamicData.Tests/Cache/XorFixture.cs b/src/DynamicData.Tests/Cache/XorFixture.cs index c92beb3b5..8a320430a 100644 --- a/src/DynamicData.Tests/Cache/XorFixture.cs +++ b/src/DynamicData.Tests/Cache/XorFixture.cs @@ -11,10 +11,7 @@ namespace DynamicData.Tests.Cache; public class XOrFixture : XOrFixtureBase { - protected override IObservable> CreateObservable() - { - return _source1.Connect().Xor(_source2.Connect()); - } + protected override IObservable> CreateObservable() => _source1.Connect().Xor(_source2.Connect()); } public class XOrCollectionFixture : XOrFixtureBase @@ -34,6 +31,7 @@ public abstract class XOrFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected XOrFixtureBase() { _source1 = new SourceCache(p => p.Name); diff --git a/src/DynamicData.Tests/Domain/Market.cs b/src/DynamicData.Tests/Domain/Market.cs index e32439a58..b7c23b76a 100644 --- a/src/DynamicData.Tests/Domain/Market.cs +++ b/src/DynamicData.Tests/Domain/Market.cs @@ -101,11 +101,9 @@ public Market SetPrices(int minId, int maxId, Func getPrice) => th private class RatingComparer : IComparer { - public int Compare([DisallowNull] IMarket x, [DisallowNull] IMarket y) - { + public int Compare([DisallowNull] IMarket x, [DisallowNull] IMarket y) => // Higher ratings go first - return y.Rating.CompareTo(x.Rating); - } + y.Rating.CompareTo(x.Rating); } } diff --git a/src/DynamicData.Tests/Domain/ParentAndChildren.cs b/src/DynamicData.Tests/Domain/ParentAndChildren.cs index 7b9a27bfa..746d45fa9 100644 --- a/src/DynamicData.Tests/Domain/ParentAndChildren.cs +++ b/src/DynamicData.Tests/Domain/ParentAndChildren.cs @@ -27,19 +27,13 @@ public ParentAndChildren(string parentId, Optional parent, Person[] chil public string? ParentId { get; } - public static bool operator ==(ParentAndChildren left, ParentAndChildren right) - { - return Equals(left, right); - } + public static bool operator ==(ParentAndChildren left, ParentAndChildren right) => Equals(left, right); - public static bool operator !=(ParentAndChildren left, ParentAndChildren right) - { - return !Equals(left, right); - } + public static bool operator !=(ParentAndChildren left, ParentAndChildren right) => !Equals(left, right); public bool Equals(ParentAndChildren? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -54,7 +48,7 @@ public bool Equals(ParentAndChildren? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -72,13 +66,7 @@ public override bool Equals(object? obj) return Equals((ParentAndChildren)obj); } - public override int GetHashCode() - { - return (ParentId is not null ? ParentId.GetHashCode() : 0); - } + public override int GetHashCode() => (ParentId is not null ? ParentId.GetHashCode() : 0); - public override string ToString() - { - return $"{nameof(Parent)}: {Parent}, ({Count} children)"; - } + public override string ToString() => $"{nameof(Parent)}: {Parent}, ({Count} children)"; } diff --git a/src/DynamicData.Tests/Domain/ParentChild.cs b/src/DynamicData.Tests/Domain/ParentChild.cs index ec6dcda0a..d907d62e7 100644 --- a/src/DynamicData.Tests/Domain/ParentChild.cs +++ b/src/DynamicData.Tests/Domain/ParentChild.cs @@ -1,14 +1,8 @@ namespace DynamicData.Tests.Domain; -public class ParentChild +public class ParentChild(Person child, Person parent) { - public ParentChild(Person child, Person parent) - { - Child = child; - Parent = parent; - } + public Person Child { get; } = child; - public Person Child { get; } - - public Person Parent { get; } + public Person Parent { get; } = parent; } diff --git a/src/DynamicData.Tests/Domain/Person.cs b/src/DynamicData.Tests/Domain/Person.cs index bcc516a53..67a1ed03d 100644 --- a/src/DynamicData.Tests/Domain/Person.cs +++ b/src/DynamicData.Tests/Domain/Person.cs @@ -60,19 +60,13 @@ public int? AgeNullable public string ParentName { get; } - public static bool operator ==(Person left, Person right) - { - return Equals(left, right); - } + public static bool operator ==(Person left, Person right) => Equals(left, right); - public static bool operator !=(Person left, Person right) - { - return !Equals(left, right); - } + public static bool operator !=(Person left, Person right) => !Equals(left, right); public bool Equals(Person? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -87,7 +81,7 @@ public bool Equals(Person? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -105,15 +99,9 @@ public override bool Equals(object? obj) return Equals((Person)obj); } - public override int GetHashCode() - { - return (Name is not null ? Name.GetHashCode() : 0); - } + public override int GetHashCode() => (Name is not null ? Name.GetHashCode() : 0); - public override string ToString() - { - return $"{Name}. {Age}"; - } + public override string ToString() => $"{Name}. {Age}"; private sealed class AgeEqualityComparer : IEqualityComparer { @@ -124,12 +112,12 @@ public bool Equals(Person? x, Person? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } @@ -142,10 +130,7 @@ public bool Equals(Person? x, Person? y) return x._age == y._age; } - public int GetHashCode(Person obj) - { - return obj._age; - } + public int GetHashCode(Person obj) => obj._age; } private sealed class NameAgeGenderEqualityComparer : IEqualityComparer @@ -157,12 +142,12 @@ public bool Equals(Person? x, Person? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } diff --git a/src/DynamicData.Tests/Domain/PersonEmployment.cs b/src/DynamicData.Tests/Domain/PersonEmployment.cs index 5ac4c06c6..4770b45ba 100644 --- a/src/DynamicData.Tests/Domain/PersonEmployment.cs +++ b/src/DynamicData.Tests/Domain/PersonEmployment.cs @@ -1,6 +1,9 @@ +using System; + namespace DynamicData.Tests.Domain; -public struct PersonEmpKey +[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1066:Implement IEquatable when overriding Object.Equals", Justification = "Acceptable in a test.")] +public readonly struct PersonEmpKey { private readonly string _name; @@ -12,20 +15,18 @@ public PersonEmpKey(string name, string company) _company = company; } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Acceptable in a test.")] public PersonEmpKey(PersonEmployment personEmployment) { _name = personEmployment.Name; _company = personEmployment.Company; } - public bool Equals(PersonEmpKey other) - { - return string.Equals(_name, other._name) && string.Equals(_company, other._company); - } + public bool Equals(PersonEmpKey other) => string.Equals(_name, other._name) && string.Equals(_company, other._company); public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -41,15 +42,9 @@ public override int GetHashCode() } } - public static bool operator ==(PersonEmpKey left, PersonEmpKey right) - { - return left.Equals(right); - } + public static bool operator ==(PersonEmpKey left, PersonEmpKey right) => left.Equals(right); - public static bool operator !=(PersonEmpKey left, PersonEmpKey right) - { - return !(left == right); - } + public static bool operator !=(PersonEmpKey left, PersonEmpKey right) => !(left == right); } public class PersonEmployment : IKey @@ -69,7 +64,7 @@ public PersonEmployment(string name, string company) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -95,13 +90,8 @@ public override int GetHashCode() } } - public override string ToString() - { - return string.Format("Name: {0}, Company: {1}", Name, Company); - } + public override string ToString() => string.Format("Name: {0}, Company: {1}", Name, Company); - protected bool Equals(PersonEmployment other) - { - return string.Equals(Name, other.Name) && string.Equals(Company, other.Company); - } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "Acceptable in a test.")] + protected bool Equals(PersonEmployment other) => string.Equals(Name, other.Name) && string.Equals(Company, other.Company); } diff --git a/src/DynamicData.Tests/Domain/PersonObs.cs b/src/DynamicData.Tests/Domain/PersonObs.cs index bb14f966c..08bd463b7 100644 --- a/src/DynamicData.Tests/Domain/PersonObs.cs +++ b/src/DynamicData.Tests/Domain/PersonObs.cs @@ -4,50 +4,37 @@ namespace DynamicData.Tests.Domain; -public class PersonObs : IEquatable +[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1001:Types that own disposable fields should be disposable", Justification = "Acceptable in test.")] +public class PersonObs(string name, int age, string gender = "F", string? parentName = null) : IEquatable { - private readonly BehaviorSubject _age; + private readonly BehaviorSubject _age = new BehaviorSubject(age); public PersonObs(string firstname, string lastname, int age, string gender = "F", string? parentName = null) : this(firstname + " " + lastname, age, gender, parentName) { } - public PersonObs(string name, int age, string gender = "F", string? parentName = null) - { - Name = name; - _age = new BehaviorSubject(age); - Gender = gender; - ParentName = parentName ?? string.Empty; - } - public static IEqualityComparer AgeComparer { get; } = new AgeEqualityComparer(); public static IEqualityComparer NameAgeGenderComparer { get; } = new NameAgeGenderEqualityComparer(); public IObservable Age => _age; - public string Gender { get; } + public string Gender { get; } = gender; public string Key => Name; - public string Name { get; } + public string Name { get; } = name; - public string ParentName { get; } + public string ParentName { get; } = parentName ?? string.Empty; - public static bool operator ==(PersonObs left, PersonObs right) - { - return Equals(left, right); - } + public static bool operator ==(PersonObs left, PersonObs right) => Equals(left, right); - public static bool operator !=(PersonObs left, PersonObs right) - { - return !Equals(left, right); - } + public static bool operator !=(PersonObs left, PersonObs right) => !Equals(left, right); public bool Equals(PersonObs? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -62,7 +49,7 @@ public bool Equals(PersonObs? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -80,20 +67,11 @@ public override bool Equals(object? obj) return Equals((PersonObs)obj); } - public override int GetHashCode() - { - return (Name is not null ? Name.GetHashCode() : 0); - } + public override int GetHashCode() => (Name is not null ? Name.GetHashCode() : 0); - public void SetAge(int age) - { - _age.OnNext(age); - } + public void SetAge(int age) => _age.OnNext(age); - public override string ToString() - { - return $"{Name}. {_age.Value}"; - } + public override string ToString() => $"{Name}. {_age.Value}"; private sealed class AgeEqualityComparer : IEqualityComparer { @@ -104,12 +82,12 @@ public bool Equals(PersonObs? x, PersonObs? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } @@ -122,10 +100,7 @@ public bool Equals(PersonObs? x, PersonObs? y) return x._age.Value == y._age.Value; } - public int GetHashCode(PersonObs obj) - { - return obj._age.Value; - } + public int GetHashCode(PersonObs obj) => obj._age.Value; } private sealed class NameAgeGenderEqualityComparer : IEqualityComparer @@ -137,12 +112,12 @@ public bool Equals(PersonObs? x, PersonObs? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } diff --git a/src/DynamicData.Tests/Domain/PersonWithChildren.cs b/src/DynamicData.Tests/Domain/PersonWithChildren.cs index de3104f64..9930cf7cb 100644 --- a/src/DynamicData.Tests/Domain/PersonWithChildren.cs +++ b/src/DynamicData.Tests/Domain/PersonWithChildren.cs @@ -32,8 +32,5 @@ public PersonWithChildren(string name, int age, IEnumerable relations) public IEnumerable Relations { get; } - public override string ToString() - { - return $"{Name}. {Age}"; - } + public override string ToString() => $"{Name}. {Age}"; } diff --git a/src/DynamicData.Tests/Domain/PersonWithEmployment.cs b/src/DynamicData.Tests/Domain/PersonWithEmployment.cs index c79b9dd36..c95e9ce75 100644 --- a/src/DynamicData.Tests/Domain/PersonWithEmployment.cs +++ b/src/DynamicData.Tests/Domain/PersonWithEmployment.cs @@ -2,29 +2,17 @@ namespace DynamicData.Tests.Domain; -public class PersonWithEmployment : IDisposable +public class PersonWithEmployment(IGroup source) : IDisposable { - private readonly IGroup _source; - - public PersonWithEmployment(IGroup source) - { - _source = source; - EmploymentData = source.Cache; - } + private readonly IGroup _source = source; public int EmploymentCount => EmploymentData.Count; - public IObservableCache EmploymentData { get; } + public IObservableCache EmploymentData { get; } = source?.Cache!; public string Person => _source.Key; - public void Dispose() - { - EmploymentData.Dispose(); - } + public void Dispose() => EmploymentData.Dispose(); - public override string ToString() - { - return $"Person: {Person}. Count {EmploymentCount}"; - } + public override string ToString() => $"Person: {Person}. Count {EmploymentCount}"; } diff --git a/src/DynamicData.Tests/Domain/PersonWithFriends.cs b/src/DynamicData.Tests/Domain/PersonWithFriends.cs index 4f84e20e7..43db20717 100644 --- a/src/DynamicData.Tests/Domain/PersonWithFriends.cs +++ b/src/DynamicData.Tests/Domain/PersonWithFriends.cs @@ -5,25 +5,17 @@ namespace DynamicData.Tests.Domain; -public class PersonWithFriends : AbstractNotifyPropertyChanged, IKey +public class PersonWithFriends(string name, int age, IEnumerable friends) : AbstractNotifyPropertyChanged, IKey { - private int _age; + private int _age = age; - private IEnumerable _friends; + private IEnumerable _friends = friends; public PersonWithFriends(string name, int age) : this(name, age, Enumerable.Empty()) { } - public PersonWithFriends(string name, int age, IEnumerable friends) - { - Name = name; - _age = age; - _friends = friends; - Key = name; - } - public int Age { get => _age; @@ -39,12 +31,9 @@ public IEnumerable Friends /// /// The key /// - public string Key { get; } + public string Key { get; } = name; - public string Name { get; } + public string Name { get; } = name; - public override string ToString() - { - return $"{Name}. {Age}"; - } + public override string ToString() => $"{Name}. {Age}"; } diff --git a/src/DynamicData.Tests/Domain/PersonWithGender.cs b/src/DynamicData.Tests/Domain/PersonWithGender.cs index c71d37d2f..7f6f8203e 100644 --- a/src/DynamicData.Tests/Domain/PersonWithGender.cs +++ b/src/DynamicData.Tests/Domain/PersonWithGender.cs @@ -6,7 +6,7 @@ public class PersonWithGender : IEquatable { public PersonWithGender(Person person, string gender) { - Name = person.Name; + Name = person?.Name!; Age = person.Age; Gender = gender; } @@ -26,7 +26,7 @@ public PersonWithGender(string name, int age, string gender) public bool Equals(PersonWithGender? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -41,7 +41,7 @@ public bool Equals(PersonWithGender? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -70,8 +70,5 @@ public override int GetHashCode() } } - public override string ToString() - { - return $"{this.Name}. {this.Age} ({Gender})"; - } + public override string ToString() => $"{Name}. {Age} ({Gender})"; } diff --git a/src/DynamicData.Tests/Domain/PersonWithRelations.cs b/src/DynamicData.Tests/Domain/PersonWithRelations.cs index 74ec2c830..f488865f5 100644 --- a/src/DynamicData.Tests/Domain/PersonWithRelations.cs +++ b/src/DynamicData.Tests/Domain/PersonWithRelations.cs @@ -35,8 +35,5 @@ public PersonWithRelations(string name, int age, IEnumerable Relations { get; } - public override string ToString() - { - return $"{Name}. {Age}"; - } + public override string ToString() => $"{Name}. {Age}"; } diff --git a/src/DynamicData.Tests/Domain/SelfObservingPerson.cs b/src/DynamicData.Tests/Domain/SelfObservingPerson.cs index ed55f078f..7a11ea949 100644 --- a/src/DynamicData.Tests/Domain/SelfObservingPerson.cs +++ b/src/DynamicData.Tests/Domain/SelfObservingPerson.cs @@ -7,15 +7,12 @@ public class SelfObservingPerson : IDisposable { private readonly IDisposable _cleanUp; - public SelfObservingPerson(IObservable observable) - { - _cleanUp = observable.Finally(() => Completed = true).Subscribe( + public SelfObservingPerson(IObservable observable) => _cleanUp = observable.Finally(() => Completed = true).Subscribe( p => { Person = p; UpdateCount++; }); - } public bool Completed { get; private set; } @@ -26,8 +23,5 @@ public SelfObservingPerson(IObservable observable) /// ///put here the code to dispose all managed and unmanaged resources /// - public void Dispose() - { - _cleanUp.Dispose(); - } + public void Dispose() => _cleanUp.Dispose(); } diff --git a/src/DynamicData.Tests/DynamicData.Tests.csproj b/src/DynamicData.Tests/DynamicData.Tests.csproj index d9100d7f9..eb5193052 100644 --- a/src/DynamicData.Tests/DynamicData.Tests.csproj +++ b/src/DynamicData.Tests/DynamicData.Tests.csproj @@ -1,7 +1,7 @@  net6.0;net7.0;net8.0 - $(NoWarn);CS0618;CA1801;CA1063;CS8767;CS8602;CS8618;IDE1006 + $(NoWarn);CS0618;CA1801;CA1812;CA1816;CA1063;CS8767;CS8602;CS8618;IDE1006 enable latest 2.6.2 diff --git a/src/DynamicData.Tests/Issues/OnItemRemovedIssue.cs b/src/DynamicData.Tests/Issues/OnItemRemovedIssue.cs index 07d0e8e99..d257b8abb 100644 --- a/src/DynamicData.Tests/Issues/OnItemRemovedIssue.cs +++ b/src/DynamicData.Tests/Issues/OnItemRemovedIssue.cs @@ -16,8 +16,8 @@ public void ListAndCacheShouldHaveEquivalentBehaviour() { var source = new ObservableCollection { - new Item { Id = 1 }, - new Item { Id = 2 } + new() { Id = 1 }, + new() { Id = 2 } }; var list = source.ToObservableChangeSet() @@ -58,9 +58,9 @@ public class Proxy public class ProxyEqualityComparer : IEqualityComparer { - public bool Equals(Proxy x, Proxy y) => x.Item.Id == y.Item.Id && x.Active == y.Active; + public bool Equals(Proxy x, Proxy y) => x?.Item.Id == y?.Item.Id && x.Active == y.Active; - public int GetHashCode(Proxy obj) => HashCode.Combine(obj.Active, obj.Item); + public int GetHashCode(Proxy obj) => HashCode.Combine(obj?.Active, obj.Item); } } } diff --git a/src/DynamicData.Tests/List/AndFixture.cs b/src/DynamicData.Tests/List/AndFixture.cs index 3801de376..1d18596ad 100644 --- a/src/DynamicData.Tests/List/AndFixture.cs +++ b/src/DynamicData.Tests/List/AndFixture.cs @@ -10,10 +10,7 @@ namespace DynamicData.Tests.List; public class AndFixture : AndFixtureBase { - protected override IObservable> CreateObservable() - { - return _source1.Connect().And(_source2.Connect()); - } + protected override IObservable> CreateObservable() => _source1.Connect().And(_source2.Connect()); } public class AndCollectionFixture : AndFixtureBase @@ -33,6 +30,7 @@ public abstract class AndFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected AndFixtureBase() { _source1 = new SourceList(); diff --git a/src/DynamicData.Tests/List/AutoRefreshFixture.cs b/src/DynamicData.Tests/List/AutoRefreshFixture.cs index 428feaff0..15af100d3 100644 --- a/src/DynamicData.Tests/List/AutoRefreshFixture.cs +++ b/src/DynamicData.Tests/List/AutoRefreshFixture.cs @@ -368,16 +368,11 @@ public int Value } } - private class SelectableItem : AbstractNotifyPropertyChanged + private class SelectableItem(int id) : AbstractNotifyPropertyChanged { private bool _isSelected; - public SelectableItem(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public bool IsSelected { @@ -387,7 +382,7 @@ public bool IsSelected public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -405,28 +400,16 @@ public override bool Equals(object? obj) return Equals((SelectableItem)obj); } - public override int GetHashCode() - { - return Id; - } + public override int GetHashCode() => Id; - protected bool Equals(SelectableItem other) - { - return Id == other.Id; - } + protected bool Equals(SelectableItem other) => Id == other.Id; } - private class TransformedPerson + private class TransformedPerson(Person person, int index) { - public TransformedPerson(Person person, int index) - { - Person = person; - Index = index; - } - - public int Index { get; } + public int Index { get; } = index; - public Person Person { get; } + public Person Person { get; } = person; public DateTime TimeStamp { get; } = DateTime.Now; } diff --git a/src/DynamicData.Tests/List/ChangeAwareListFixture.cs b/src/DynamicData.Tests/List/ChangeAwareListFixture.cs index a032cc240..c8b65086c 100644 --- a/src/DynamicData.Tests/List/ChangeAwareListFixture.cs +++ b/src/DynamicData.Tests/List/ChangeAwareListFixture.cs @@ -13,10 +13,7 @@ public class ChangeAwareListFixture { private readonly ChangeAwareList _list; - public ChangeAwareListFixture() - { - _list = new ChangeAwareList(); - } + public ChangeAwareListFixture() => _list = new ChangeAwareList(); [Fact] public void Add() @@ -244,16 +241,10 @@ public void RemoveSucessionReversed() } [Fact] - public void ThrowWhenRemovingItemOutsideOfBoundaries() - { - Assert.Throws(() => _list.RemoveAt(0)); - } + public void ThrowWhenRemovingItemOutsideOfBoundaries() => Assert.Throws(() => _list.RemoveAt(0)); [Fact] - public void ThrowWhenRemovingRangeThatBeginsOutsideOfBoundaries() - { - Assert.Throws(() => _list.RemoveRange(0, 1)); - } + public void ThrowWhenRemovingRangeThatBeginsOutsideOfBoundaries() => Assert.Throws(() => _list.RemoveRange(0, 1)); [Fact] public void ThrowWhenRemovingRangeThatFinishesOutsideOfBoundaries() diff --git a/src/DynamicData.Tests/List/CreationFixtures.cs b/src/DynamicData.Tests/List/CreationFixtures.cs index 350dfe30d..ae7ca0d0b 100644 --- a/src/DynamicData.Tests/List/CreationFixtures.cs +++ b/src/DynamicData.Tests/List/CreationFixtures.cs @@ -13,7 +13,7 @@ public class ListCreationFixtures [Fact] public void Create() { - Task CreateTask(T value) => Task.FromResult(value); + static Task CreateTask(T value) => Task.FromResult(value); SubscribeAndAssert( ObservableChangeSet.Create( @@ -25,6 +25,7 @@ public void Create() })); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "Accetable for test.")] private void SubscribeAndAssert(IObservable> observableChangeset, bool expectsError = false) where T : notnull { diff --git a/src/DynamicData.Tests/List/DisposeManyFixture.cs b/src/DynamicData.Tests/List/DisposeManyFixture.cs index 8eb862acd..f57df2ea9 100644 --- a/src/DynamicData.Tests/List/DisposeManyFixture.cs +++ b/src/DynamicData.Tests/List/DisposeManyFixture.cs @@ -157,12 +157,9 @@ public void RemainingItemsAreDisposedAfterUnsubscription() items.All(item => item.IsDisposed).Should().BeTrue("Items remaining in the list should be disposed"); } - private class DisposableObject : IDisposable + private class DisposableObject(int id) : IDisposable { - public DisposableObject(int id) - => Id = id; - - public int Id { get; private set; } + public int Id { get; private set; } = id; public bool IsDisposed { get; private set; } diff --git a/src/DynamicData.Tests/List/ExceptFixture.cs b/src/DynamicData.Tests/List/ExceptFixture.cs index 26bf98459..d74eff07b 100644 --- a/src/DynamicData.Tests/List/ExceptFixture.cs +++ b/src/DynamicData.Tests/List/ExceptFixture.cs @@ -10,10 +10,7 @@ namespace DynamicData.Tests.List; public class ExceptFixture : ExceptFixtureBase { - protected override IObservable> CreateObservable() - { - return Source1.Connect().Except(Source2.Connect()); - } + protected override IObservable> CreateObservable() => Source1.Connect().Except(Source2.Connect()); } public class ExceptCollectionFixture : ExceptFixtureBase @@ -33,6 +30,7 @@ public abstract class ExceptFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected ExceptFixtureBase() { Source1 = new SourceList(); diff --git a/src/DynamicData.Tests/List/FilterOnObservableFixture.cs b/src/DynamicData.Tests/List/FilterOnObservableFixture.cs index 95df56648..8cb3e152b 100644 --- a/src/DynamicData.Tests/List/FilterOnObservableFixture.cs +++ b/src/DynamicData.Tests/List/FilterOnObservableFixture.cs @@ -105,10 +105,7 @@ public void RemoveRange() private class FilterPropertyStub : IDisposable { - public FilterPropertyStub() - { - Results = new ChangeSetAggregator(Source.Connect().FilterOnObservable(p => p.Age.Select(v => v > 18))); - } + public FilterPropertyStub() => Results = new ChangeSetAggregator(Source.Connect().FilterOnObservable(p => p.Age.Select(v => v > 18))); public ChangeSetAggregator Results { get; } diff --git a/src/DynamicData.Tests/List/FilterOnPropertyFixture.cs b/src/DynamicData.Tests/List/FilterOnPropertyFixture.cs index 3323f3747..9d9dbfe03 100644 --- a/src/DynamicData.Tests/List/FilterOnPropertyFixture.cs +++ b/src/DynamicData.Tests/List/FilterOnPropertyFixture.cs @@ -86,10 +86,7 @@ public void RemoveRange() private class FilterPropertyStub : IDisposable { - public FilterPropertyStub() - { - Results = new ChangeSetAggregator(Source.Connect().FilterOnProperty(p => p.Age, p => p.Age > 18)); - } + public FilterPropertyStub() => Results = new ChangeSetAggregator(Source.Connect().FilterOnProperty(p => p.Age, p => p.Age > 18)); public ChangeSetAggregator Results { get; } diff --git a/src/DynamicData.Tests/List/FilterWithObservable.cs b/src/DynamicData.Tests/List/FilterWithObservable.cs index d3ebc9e16..c64adddaa 100644 --- a/src/DynamicData.Tests/List/FilterWithObservable.cs +++ b/src/DynamicData.Tests/List/FilterWithObservable.cs @@ -170,6 +170,7 @@ public void Dispose() { _source.Dispose(); _results.Dispose(); + _filter.Dispose(); } [Fact] diff --git a/src/DynamicData.Tests/List/ForEachChangeFixture.cs b/src/DynamicData.Tests/List/ForEachChangeFixture.cs index e07707bdb..589397d31 100644 --- a/src/DynamicData.Tests/List/ForEachChangeFixture.cs +++ b/src/DynamicData.Tests/List/ForEachChangeFixture.cs @@ -14,15 +14,9 @@ public class ForEachChangeFixture : IDisposable { private readonly ISourceList _source; - public ForEachChangeFixture() - { - _source = new SourceList(); - } + public ForEachChangeFixture() => _source = new SourceList(); - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void EachChangeInokesTheCallback() diff --git a/src/DynamicData.Tests/List/FromAsyncFixture.cs b/src/DynamicData.Tests/List/FromAsyncFixture.cs index ce5785367..2f1913c48 100644 --- a/src/DynamicData.Tests/List/FromAsyncFixture.cs +++ b/src/DynamicData.Tests/List/FromAsyncFixture.cs @@ -18,10 +18,7 @@ public class FromAsyncFixture { private readonly TestScheduler _scheduler; - public FromAsyncFixture() - { - _scheduler = new TestScheduler(); - } + public FromAsyncFixture() => _scheduler = new TestScheduler(); [Fact] public void CanLoadFromTask() diff --git a/src/DynamicData.Tests/List/GroupOnFixture.cs b/src/DynamicData.Tests/List/GroupOnFixture.cs index 14c02dc4f..743e988dd 100644 --- a/src/DynamicData.Tests/List/GroupOnFixture.cs +++ b/src/DynamicData.Tests/List/GroupOnFixture.cs @@ -47,6 +47,7 @@ public void BigList() public void Dispose() { _source.Dispose(); + _results.Dispose(); } [Fact] diff --git a/src/DynamicData.Tests/List/MergeManyChangeSetsCacheFixture.cs b/src/DynamicData.Tests/List/MergeManyChangeSetsCacheFixture.cs index a2a1afa0c..56e04ef5f 100644 --- a/src/DynamicData.Tests/List/MergeManyChangeSetsCacheFixture.cs +++ b/src/DynamicData.Tests/List/MergeManyChangeSetsCacheFixture.cs @@ -36,10 +36,7 @@ public sealed class MergeManyChangeSetsCacheFixture : IDisposable private readonly ChangeSetAggregator _marketListResults; - public MergeManyChangeSetsCacheFixture() - { - _marketListResults = _marketList.Connect().AsAggregator(); - } + public MergeManyChangeSetsCacheFixture() => _marketListResults = _marketList.Connect().AsAggregator(); [Fact] public void NullChecks() diff --git a/src/DynamicData.Tests/List/MergeManyFixture.cs b/src/DynamicData.Tests/List/MergeManyFixture.cs index bda676261..997e91f9f 100644 --- a/src/DynamicData.Tests/List/MergeManyFixture.cs +++ b/src/DynamicData.Tests/List/MergeManyFixture.cs @@ -12,15 +12,9 @@ public class MergeManyFixture : IDisposable { private readonly ISourceList _source; - public MergeManyFixture() - { - _source = new SourceList(); - } + public MergeManyFixture() => _source = new SourceList(); - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void EverythingIsUnsubscribedWhenStreamIsDisposed() @@ -160,30 +154,19 @@ public void MergedStreamFailsWhenSourceFails() receivedError.Should().Be(expectedError); } - private class ObjectWithObservable + private class ObjectWithObservable(int id) { private readonly ISubject _changed = new Subject(); private bool _value; - public ObjectWithObservable(int id) - { - Id = id; - } - - public int Id { get; } + public int Id { get; } = id; public IObservable Observable => _changed; - public void CompleteObservable() - { - _changed.OnCompleted(); - } + public void CompleteObservable() => _changed.OnCompleted(); - public void FailObservable(Exception ex) - { - _changed.OnError(ex); - } + public void FailObservable(Exception ex) => _changed.OnError(ex); public void InvokeObservable(bool value) { diff --git a/src/DynamicData.Tests/List/OrFixture.cs b/src/DynamicData.Tests/List/OrFixture.cs index 140ab4175..16c09b0dd 100644 --- a/src/DynamicData.Tests/List/OrFixture.cs +++ b/src/DynamicData.Tests/List/OrFixture.cs @@ -10,10 +10,7 @@ namespace DynamicData.Tests.List; public class OrFixture : OrFixtureBase { - protected override IObservable> CreateObservable() - { - return _source1.Connect().Or(_source2.Connect()); - } + protected override IObservable> CreateObservable() => _source1.Connect().Or(_source2.Connect()); } public class OrCollectionFixture : OrFixtureBase @@ -78,6 +75,7 @@ public abstract class OrFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected OrFixtureBase() { _source1 = new SourceList(); diff --git a/src/DynamicData.Tests/List/PageFixture.cs b/src/DynamicData.Tests/List/PageFixture.cs index 1afd98a80..5091b06b7 100644 --- a/src/DynamicData.Tests/List/PageFixture.cs +++ b/src/DynamicData.Tests/List/PageFixture.cs @@ -134,7 +134,7 @@ public void VirtualiseInitial() public class PageFixtureWithNoInitialData { private readonly Animal[] _items = - { + [ new("Holly", "Cat", AnimalFamily.Mammal), new("Rover", "Dog", AnimalFamily.Mammal), new("Rex", "Dog", AnimalFamily.Mammal), @@ -145,7 +145,7 @@ public class PageFixtureWithNoInitialData new("Isaac", "Next", AnimalFamily.Amphibian), new("Sam", "Snake", AnimalFamily.Reptile), new("Sharon", "Red Backed Shrike", AnimalFamily.Bird), - }; + ]; [Fact] public void SimplePaging() @@ -193,18 +193,15 @@ public class SimplePaging : AbstractNotifyPropertyChanged, IDisposable public SimplePaging(IObservableList source, IObservable pager) { - Paged = source.Connect() + Paged = source?.Connect() .Page(pager) .Do(changes => Console.WriteLine(changes.TotalChanges)) //added as a quick and dirty way to debug - .AsObservableList(); + .AsObservableList()!; _cleanUp = Paged; } public IObservableList Paged { get; } - public void Dispose() - { - _cleanUp.Dispose(); - } + public void Dispose() => _cleanUp.Dispose(); } diff --git a/src/DynamicData.Tests/List/RecursiveTransformManyFixture.cs b/src/DynamicData.Tests/List/RecursiveTransformManyFixture.cs index 4df311c36..1d79be23e 100644 --- a/src/DynamicData.Tests/List/RecursiveTransformManyFixture.cs +++ b/src/DynamicData.Tests/List/RecursiveTransformManyFixture.cs @@ -40,6 +40,7 @@ public void ChildrenAreRemovedWhenParentIsRemoved() public void Dispose() { _source.Dispose(); + _results.Dispose(); } [Fact] diff --git a/src/DynamicData.Tests/List/RefCountFixture.cs b/src/DynamicData.Tests/List/RefCountFixture.cs index a8ff1f002..c0d86e06d 100644 --- a/src/DynamicData.Tests/List/RefCountFixture.cs +++ b/src/DynamicData.Tests/List/RefCountFixture.cs @@ -15,10 +15,7 @@ public class RefCountFixture : IDisposable { private readonly ISourceList _source; - public RefCountFixture() - { - _source = new SourceList(); - } + public RefCountFixture() => _source = new SourceList(); [Fact] public void CanResubscribe() @@ -64,10 +61,7 @@ public void ChainIsInvokedOnceForMultipleSubscribers() disposals.Should().Be(1); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); // This test is probabilistic, it could be cool to be able to prove RefCount's thread-safety // more accurately but I don't think that there is an easy way to do this. diff --git a/src/DynamicData.Tests/List/RemoveManyFixture.cs b/src/DynamicData.Tests/List/RemoveManyFixture.cs index 5a30fb5ad..b0809011e 100644 --- a/src/DynamicData.Tests/List/RemoveManyFixture.cs +++ b/src/DynamicData.Tests/List/RemoveManyFixture.cs @@ -12,10 +12,7 @@ public class RemoveManyFixture { private readonly List _list; - public RemoveManyFixture() - { - _list = new List(); - } + public RemoveManyFixture() => _list = new List(); [Fact] public void DoesNotRemoveDuplicates() diff --git a/src/DynamicData.Tests/List/SizeLimitFixture.cs b/src/DynamicData.Tests/List/SizeLimitFixture.cs index cca08d7f6..ade7cc5fe 100644 --- a/src/DynamicData.Tests/List/SizeLimitFixture.cs +++ b/src/DynamicData.Tests/List/SizeLimitFixture.cs @@ -98,9 +98,7 @@ public void ForceError() } [Fact] - public void ThrowsIfSizeLimitIsZero() - { + public void ThrowsIfSizeLimitIsZero() => // Initialise(); Assert.Throws(() => new SourceCache(p => p.Key).LimitSizeTo(0)); - } } diff --git a/src/DynamicData.Tests/List/SortFixture.cs b/src/DynamicData.Tests/List/SortFixture.cs index 37f01bc26..7a3527228 100644 --- a/src/DynamicData.Tests/List/SortFixture.cs +++ b/src/DynamicData.Tests/List/SortFixture.cs @@ -41,14 +41,9 @@ public void SortsWithoutError() } - private class ListItem : IComparable + private class ListItem(int number) : IComparable { - public int Number { get; } - - public ListItem(int number) - { - Number = number; - } + public int Number { get; } = number; public int CompareTo(ListItem? other) => DefaultComparer.Compare(this, other); diff --git a/src/DynamicData.Tests/List/SourceListPreviewFixture.cs b/src/DynamicData.Tests/List/SourceListPreviewFixture.cs index ebd6803dd..cb61bbfb5 100644 --- a/src/DynamicData.Tests/List/SourceListPreviewFixture.cs +++ b/src/DynamicData.Tests/List/SourceListPreviewFixture.cs @@ -9,10 +9,7 @@ public class SourceListPreviewFixture : IDisposable { private readonly ISourceList _source; - public SourceListPreviewFixture() - { - _source = new SourceList(); - } + public SourceListPreviewFixture() => _source = new SourceList(); [Fact] public void ChangesAreNotYetAppliedDuringPreview() @@ -24,7 +21,7 @@ public void ChangesAreNotYetAppliedDuringPreview() _ => { Assert.True(_source.Count == 0); - Assert.True(_source.Items.Count() == 0); + Assert.True(_source.Items.Any() == false); }); // Trigger a change @@ -55,10 +52,7 @@ public void ConnectPreviewPredicateIsApplied() aggregator.Dispose(); } - public void Dispose() - { - _source.Dispose(); - } + public void Dispose() => _source.Dispose(); [Fact] public void FormNewListFromChanges() @@ -89,7 +83,7 @@ public void FormNewListFromChanges() public void NoChangesAllowedDuringPreview() { // On preview, try adding an arbitrary item - var d = _source.Preview().Subscribe(_ => { Assert.Throws(() => _source.Add(1)); }); + var d = _source.Preview().Subscribe(_ => Assert.Throws(() => _source.Add(1))); // Trigger a change _source.Add(1); diff --git a/src/DynamicData.Tests/List/SubscribeManyFixture.cs b/src/DynamicData.Tests/List/SubscribeManyFixture.cs index b418ea964..cd939acc9 100644 --- a/src/DynamicData.Tests/List/SubscribeManyFixture.cs +++ b/src/DynamicData.Tests/List/SubscribeManyFixture.cs @@ -78,25 +78,14 @@ public void RemoveIsUnsubscribed() _results.Messages[1].First().Item.Current.IsSubscribed.Should().Be(false, "Should be be unsubscribed"); } - private class SubscribeableObject + private class SubscribeableObject(int id) { - public SubscribeableObject(int id) - { - Id = id; - } - public bool IsSubscribed { get; private set; } - private int Id { get; } + private int Id { get; } = id; - public void Subscribe() - { - IsSubscribed = true; - } + public void Subscribe() => IsSubscribed = true; - public void UnSubscribe() - { - IsSubscribed = false; - } + public void UnSubscribe() => IsSubscribed = false; } } diff --git a/src/DynamicData.Tests/List/TransformManyFixture.cs b/src/DynamicData.Tests/List/TransformManyFixture.cs index d062b317b..caf8bc6c7 100644 --- a/src/DynamicData.Tests/List/TransformManyFixture.cs +++ b/src/DynamicData.Tests/List/TransformManyFixture.cs @@ -88,6 +88,7 @@ public void Clear() public void Dispose() { _source.Dispose(); + _results.Dispose(); } [Fact] @@ -195,19 +196,11 @@ public void Replace() _results.Data.Items.Should().BeEquivalentTo(new[] { child1, child2, frientofchild1, child4}); } - public class Tour + public class Tour(string name) { - public Tour(string name) - { - Name = name; - } + public string Name { get; } = name; - public string Name { get; } - - public override string ToString() - { - return $"{nameof(Name)}: {Name}"; - } + public override string ToString() => $"{nameof(Name)}: {Name}"; } public class TourProvider @@ -224,6 +217,6 @@ public TourProvider(string name, IEnumerable? tours) public string Name { get; } - public ObservableCollection Tours { get; } = new ObservableCollection(); + public ObservableCollection Tours { get; } = []; } } diff --git a/src/DynamicData.Tests/List/TransformManyProjectionFixture.cs b/src/DynamicData.Tests/List/TransformManyProjectionFixture.cs index dcbedf16c..49c34de51 100644 --- a/src/DynamicData.Tests/List/TransformManyProjectionFixture.cs +++ b/src/DynamicData.Tests/List/TransformManyProjectionFixture.cs @@ -53,6 +53,7 @@ public void AddRange() public void Dispose() { _source.Dispose(); + _results.Dispose(); } [Fact] @@ -111,43 +112,25 @@ public void RemoveParent() _results.Items.Should().BeEquivalentTo(parents.Skip(1).SelectMany(p => p.Children.Select(c => new ProjectedNestedChild(p, c)))); } - private class ClassWithNestedObservableCollection + private class ClassWithNestedObservableCollection(int id, IEnumerable animals) { - public ClassWithNestedObservableCollection(int id, IEnumerable animals) - { - Id = id; - Children = new ObservableCollection(animals); - } - - public ObservableCollection Children { get; } + public ObservableCollection Children { get; } = new(animals); - public int Id { get; } + public int Id { get; } = id; } - private class NestedChild + private class NestedChild(string name, string value) { - public NestedChild(string name, string value) - { - Name = name; - Value = value; - } - - public string Name { get; } + public string Name { get; } = name; - public string Value { get; } + public string Value { get; } = value; } - private class ProjectedNestedChild + private class ProjectedNestedChild(ClassWithNestedObservableCollection parent, NestedChild child) { - public ProjectedNestedChild(ClassWithNestedObservableCollection parent, NestedChild child) - { - Parent = parent; - Child = child; - } - - public NestedChild Child { get; } + public NestedChild Child { get; } = child; - public ClassWithNestedObservableCollection Parent { get; } + public ClassWithNestedObservableCollection Parent { get; } = parent; } private class ProjectNestedChildEqualityComparer : IEqualityComparer @@ -160,9 +143,6 @@ public bool Equals(ProjectedNestedChild? x, ProjectedNestedChild? y) return x.Child.Name == y.Child.Name; } - public int GetHashCode(ProjectedNestedChild obj) - { - return obj.Child.Name.GetHashCode(); - } + public int GetHashCode(ProjectedNestedChild obj) => obj.Child.Name.GetHashCode(); } } diff --git a/src/DynamicData.Tests/List/XOrFixture.cs b/src/DynamicData.Tests/List/XOrFixture.cs index e1149990c..70a23e62e 100644 --- a/src/DynamicData.Tests/List/XOrFixture.cs +++ b/src/DynamicData.Tests/List/XOrFixture.cs @@ -10,10 +10,7 @@ namespace DynamicData.Tests.List; public class XOrFixture : XOrFixtureBase { - protected override IObservable> CreateObservable() - { - return _source1.Connect().Xor(_source2.Connect()); - } + protected override IObservable> CreateObservable() => _source1.Connect().Xor(_source2.Connect()); } public class XOrCollectionFixture : XOrFixtureBase @@ -33,6 +30,7 @@ public abstract class XOrFixtureBase : IDisposable private readonly ChangeSetAggregator _results; + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2214:Do not call overridable methods in constructors", Justification = "Accepted as part of a test.")] protected XOrFixtureBase() { _source1 = new SourceList(); diff --git a/src/DynamicData.Tests/Utilities/ComparerExtensions.cs b/src/DynamicData.Tests/Utilities/ComparerExtensions.cs index 1908f4cf8..9bace663b 100644 --- a/src/DynamicData.Tests/Utilities/ComparerExtensions.cs +++ b/src/DynamicData.Tests/Utilities/ComparerExtensions.cs @@ -16,11 +16,9 @@ internal class NoOpEqualityComparer : IEqualityComparer } -internal class InvertedComparer : IComparer +internal class InvertedComparer(IComparer original) : IComparer { - private readonly IComparer _original; - - public InvertedComparer(IComparer original) => _original = original; + private readonly IComparer _original = original; public int Compare(T x, T y) => _original.Compare(x, y) * -1; } diff --git a/src/DynamicData.Tests/Utilities/ObservableSpy.cs b/src/DynamicData.Tests/Utilities/ObservableSpy.cs index 3854eed76..40bcd985e 100644 --- a/src/DynamicData.Tests/Utilities/ObservableSpy.cs +++ b/src/DynamicData.Tests/Utilities/ObservableSpy.cs @@ -36,7 +36,7 @@ public static IObservable Spy(this IObservable source, string? infoText logger("Creating Observable"); - int subscriptionCounter = 0; + var subscriptionCounter = 0; return Observable.Create(obs => { var valueCounter = 0; @@ -77,7 +77,7 @@ public static IObservable Spy(this IObservable source, string? infoText } } subscription?.Dispose(); - int count = Interlocked.Decrement(ref subscriptionCounter); + var count = Interlocked.Decrement(ref subscriptionCounter); if (showSubs) { logger($"Dispose Completed! ({count} Active Subscriptions)"); @@ -86,7 +86,7 @@ public static IObservable Spy(this IObservable source, string? infoText } finally { - int count = Interlocked.Increment(ref subscriptionCounter); + var count = Interlocked.Increment(ref subscriptionCounter); if (showSubs) { logger($"Subscription Created! ({count} Active Subscriptions)"); @@ -102,7 +102,7 @@ public static IObservable> Spy(this IObservable t?.ToString() ?? "{Null}"); + formatter ??= (t => t?.ToString() ?? "{Null}"); return Spy(source, opName, logger, cs => "[Cache Change Set]" + ChangeSetEntrySpacing + string.Join(ChangeSetEntrySpacing, cs.Select((change, n) => $"#{n} [{change.Reason}] {change.Key}: {FormatChange(formatter!, change)}")), showSubs, showTimestamps); } @@ -113,48 +113,45 @@ public static IObservable> Spy(this IObservable> bool showTimestamps = true) where T : notnull { - formatter = formatter ?? (t => t?.ToString() ?? "{Null}"); + formatter ??= (t => t?.ToString() ?? "{Null}"); return Spy(source, opName, logger, cs => "[List Change Set]" + ChangeSetEntrySpacing + string.Join(ChangeSetEntrySpacing, cs.Select(change => $"[{change.Reason}] {FormatChange(formatter!, change)}")), showSubs, showTimestamps); } public static IObservable DebugSpy(this IObservable source, string? opName = null, Func? formatter = null, bool showSubs = true, - bool showTimestamps = true) - { + bool showTimestamps = true) => #if DEBUG - return source.Spy(opName, DebugLogger, formatter, showSubs, showTimestamps); + source.Spy(opName, DebugLogger, formatter, showSubs, showTimestamps); #else - return source; + source; #endif - } + public static IObservable> DebugSpy(this IObservable> source, string? opName = null, Func? formatter = null, bool showSubs = true, bool showTimestamps = true) where T : notnull - where TKey : notnull - { + where TKey : notnull => #if DEBUG - return source.Spy(opName, DebugLogger, formatter, showSubs, showTimestamps); + source.Spy(opName, DebugLogger, formatter, showSubs, showTimestamps); #else - return source; + source; #endif - } + public static IObservable> DebugSpy(this IObservable> source, string? opName = null, Func? formatter = null, bool showSubs = true, bool showTimestamps = true) - where T : notnull - { + where T : notnull => #if DEBUG - return source.Spy(opName, DebugLogger, formatter, showSubs, showTimestamps); + source.Spy(opName, DebugLogger, formatter, showSubs, showTimestamps); #else - return source; + source; #endif - } + private static string FormatChange(Func formatter, Change change) where T : notnull @@ -175,7 +172,7 @@ private static string FormatChange(Func formatter, Change chang }; private static Action CreateLogger(Action baseLogger, Func timeStamper, string opName) => - msg => baseLogger($"{timeStamper()}[{Thread.CurrentThread.ManagedThreadId:X2}] |{opName}| {msg}"); + msg => baseLogger($"{timeStamper()}[{Environment.CurrentManagedThreadId:X2}] |{opName}| {msg}"); #if DEBUG static void DebugLogger(string str) => Debug.WriteLine(str); diff --git a/src/DynamicData.Tests/Utilities/SelectManyExtensions.cs b/src/DynamicData.Tests/Utilities/SelectManyExtensions.cs index 150180b66..61c5b3445 100644 --- a/src/DynamicData.Tests/Utilities/SelectManyExtensions.cs +++ b/src/DynamicData.Tests/Utilities/SelectManyExtensions.cs @@ -9,30 +9,15 @@ namespace DynamicData.Tests.Utilities; /// public static class SelectManyExtensions { - public static IEnumerable EmptyIfNull(this IEnumerable source) - { - return source ?? Enumerable.Empty(); - } + public static IEnumerable EmptyIfNull(this IEnumerable source) => source ?? Enumerable.Empty(); - public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector) - { - return RecursiveSelect(source, childSelector, element => element); - } + public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector) => RecursiveSelect(source, childSelector, element => element); - public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector) - { - return RecursiveSelect(source, childSelector, (element, index, depth) => selector(element)); - } + public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector) => RecursiveSelect(source, childSelector, (element, index, depth) => selector(element)); - public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector) - { - return RecursiveSelect(source, childSelector, (element, index, depth) => selector(element, index)); - } + public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector) => RecursiveSelect(source, childSelector, (element, index, depth) => selector(element, index)); - public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector) - { - return RecursiveSelect(source, childSelector, selector, 0); - } + public static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector) => RecursiveSelect(source, childSelector, selector, 0); public static IEnumerable SelectManyRecursive(this IEnumerable source, Func> selector) { @@ -50,8 +35,5 @@ public static IEnumerable SelectManyRecursive(this IEnumerable source, return !selectManyRecursive.Any() ? selectManyRecursive : selectManyRecursive.Concat(selectManyRecursive.SelectMany(i => selector(i).EmptyIfNull()).SelectManyRecursive(selector)); } - private static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector, int depth) - { - return source.SelectMany((element, index) => Enumerable.Repeat(selector(element, index, depth), 1).Concat(RecursiveSelect(childSelector(element) ?? Enumerable.Empty(), childSelector, selector, depth + 1))); - } + private static IEnumerable RecursiveSelect(this IEnumerable source, Func> childSelector, Func selector, int depth) => source.SelectMany((element, index) => Enumerable.Repeat(selector(element, index, depth), 1).Concat(RecursiveSelect(childSelector(element) ?? Enumerable.Empty(), childSelector, selector, depth + 1))); } diff --git a/src/DynamicData/Aggregation/AggregateItem.cs b/src/DynamicData/Aggregation/AggregateItem.cs index e69c0ff90..45454d5a6 100644 --- a/src/DynamicData/Aggregation/AggregateItem.cs +++ b/src/DynamicData/Aggregation/AggregateItem.cs @@ -25,12 +25,12 @@ public readonly struct AggregateItem(AggregateType type, TObject item) /// public TObject Item { get; } = item; - public static bool operator ==(AggregateItem left, AggregateItem right) => left.Equals(right); + public static bool operator ==(in AggregateItem left, in AggregateItem right) => left.Equals(right); - public static bool operator !=(AggregateItem left, AggregateItem right) => !(left == right); + public static bool operator !=(in AggregateItem left, in AggregateItem right) => !(left == right); /// - public override bool Equals(object? obj) => obj is AggregateItem item && Equals(item); + public override bool Equals(object? obj) => obj is AggregateItem aggItem && Equals(aggItem); /// public bool Equals(AggregateItem other) => diff --git a/src/DynamicData/Aggregation/AggregationEx.cs b/src/DynamicData/Aggregation/AggregationEx.cs index e620eab22..55c031da4 100644 --- a/src/DynamicData/Aggregation/AggregationEx.cs +++ b/src/DynamicData/Aggregation/AggregationEx.cs @@ -23,11 +23,7 @@ public static IObservable> ForAggregation (IAggregateChangeSet)new AggregateEnumerator(changeSet)); } @@ -40,11 +36,7 @@ public static IObservable> ForAggregation> ForAggregation(this IObservable> source) where TObject : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select(changeSet => (IAggregateChangeSet)new AggregateEnumerator(changeSet)); } @@ -116,25 +108,10 @@ internal static IObservable Accumulate(this IOb /// An observable with the accumulated value. internal static IObservable Accumulate(this IObservable> source, TResult seed, Func accessor, Func addAction, Func removeAction) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (accessor is null) - { - throw new ArgumentNullException(nameof(accessor)); - } - - if (addAction is null) - { - throw new ArgumentNullException(nameof(addAction)); - } - - if (removeAction is null) - { - throw new ArgumentNullException(nameof(removeAction)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + accessor.ThrowArgumentNullExceptionIfNull(nameof(accessor)); + addAction.ThrowArgumentNullExceptionIfNull(nameof(addAction)); + removeAction.ThrowArgumentNullExceptionIfNull(nameof(removeAction)); return source.Scan(seed, (state, changes) => changes.Aggregate(state, (current, aggregateItem) => diff --git a/src/DynamicData/Aggregation/AvgEx.cs b/src/DynamicData/Aggregation/AvgEx.cs index 7c1c34f11..afbc30f90 100644 --- a/src/DynamicData/Aggregation/AvgEx.cs +++ b/src/DynamicData/Aggregation/AvgEx.cs @@ -409,38 +409,11 @@ public static IObservable Avg(this IObservable> source, private static IObservable AvgCalc(this IObservable> source, Func valueSelector, TResult fallbackValue, Func, TValue, Avg> addAction, Func, TValue, Avg> removeAction, Func, TResult> resultAction) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - ArgumentNullException.ThrowIfNull(valueSelector); - ArgumentNullException.ThrowIfNull(addAction); - ArgumentNullException.ThrowIfNull(removeAction); - ArgumentNullException.ThrowIfNull(resultAction); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } - - if (addAction is null) - { - throw new ArgumentNullException(nameof(addAction)); - } - - if (removeAction is null) - { - throw new ArgumentNullException(nameof(removeAction)); - } - - if (resultAction is null) - { - throw new ArgumentNullException(nameof(resultAction)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); + addAction.ThrowArgumentNullExceptionIfNull(nameof(addAction)); + removeAction.ThrowArgumentNullExceptionIfNull(nameof(removeAction)); + resultAction.ThrowArgumentNullExceptionIfNull(nameof(resultAction)); return source.Scan(default(Avg), (state, changes) => changes.Aggregate(state, (current, aggregateItem) => diff --git a/src/DynamicData/Aggregation/MaxEx.cs b/src/DynamicData/Aggregation/MaxEx.cs index 2ce9964e5..e09e09e45 100644 --- a/src/DynamicData/Aggregation/MaxEx.cs +++ b/src/DynamicData/Aggregation/MaxEx.cs @@ -83,20 +83,8 @@ public static IObservable Minimum(this IObserva private static IObservable Calculate(this IObservable> source, Func valueSelector, MaxOrMin maxOrMin, TResult emptyValue = default) where TResult : struct, IComparable { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Scan( default(TResult?), @@ -159,14 +147,7 @@ private static IObservable> ToChangesAndCollection where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Publish( shared => @@ -180,14 +161,7 @@ private static IObservable> ToChangesAndCollection private static IObservable> ToChangesAndCollection(this IObservable> source) where TObject : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Publish( shared => @@ -198,7 +172,7 @@ private static IObservable> ToChangesAndCollection }); } - private class ChangesAndCollection(IAggregateChangeSet changes, IReadOnlyCollection collection) + private sealed class ChangesAndCollection(IAggregateChangeSet changes, IReadOnlyCollection collection) { public IAggregateChangeSet Changes { get; } = changes; diff --git a/src/DynamicData/Aggregation/StdDevEx.cs b/src/DynamicData/Aggregation/StdDevEx.cs index c37e98c63..54de3b9e4 100644 --- a/src/DynamicData/Aggregation/StdDevEx.cs +++ b/src/DynamicData/Aggregation/StdDevEx.cs @@ -161,8 +161,7 @@ public static IObservable StdDev(this IObservableThe fallback value. /// An observable which emits the standard deviation value. public static IObservable StdDev(this IObservable> source, Func valueSelector, decimal fallbackValue = 0M) => - //// throw new NotImplementedException("For some reason there is a problem with decimal value inference"); - source.StdDevCalc(valueSelector, fallbackValue, (current, item) => new StdDev(current.Count + 1, current.SumOfItems + item, current.SumOfSquares + (item * item)), (current, item) => new StdDev(current.Count - 1, current.SumOfItems - item, current.SumOfSquares - (item * item)), values => Sqrt((decimal)(values.SumOfSquares - ((values.SumOfItems * values.SumOfItems) / values.Count))) * (1.0M / (values.Count - 1))); + source.StdDevCalc(valueSelector, fallbackValue, (current, item) => new StdDev(current.Count + 1, current.SumOfItems + item, current.SumOfSquares + (item * item)), (current, item) => new StdDev(current.Count - 1, current.SumOfItems - item, current.SumOfSquares - (item * item)), values => Sqrt(values.SumOfSquares - ((values.SumOfItems * values.SumOfItems) / values.Count)) * (1.0M / (values.Count - 1))); /// /// Continual computation of the standard deviation of the values in the underlying data source. @@ -186,38 +185,11 @@ public static IObservable StdDev(this IObservable StdDevCalc(this IObservable> source, Func valueSelector, TResult fallbackValue, Func, TValue, StdDev> addAction, Func, TValue, StdDev> removeAction, Func, TResult> resultAction) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - ArgumentNullException.ThrowIfNull(valueSelector); - ArgumentNullException.ThrowIfNull(addAction); - ArgumentNullException.ThrowIfNull(removeAction); - ArgumentNullException.ThrowIfNull(resultAction); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } - - if (addAction is null) - { - throw new ArgumentNullException(nameof(addAction)); - } - - if (removeAction is null) - { - throw new ArgumentNullException(nameof(removeAction)); - } - - if (resultAction is null) - { - throw new ArgumentNullException(nameof(resultAction)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); + addAction.ThrowArgumentNullExceptionIfNull(nameof(addAction)); + removeAction.ThrowArgumentNullExceptionIfNull(nameof(removeAction)); + resultAction.ThrowArgumentNullExceptionIfNull(nameof(resultAction)); return source.Scan(default(StdDev), (state, changes) => changes.Aggregate(state, (current, aggregateItem) => @@ -226,13 +198,20 @@ private static IObservable StdDevCalc(this IO private static decimal Sqrt(decimal x, decimal epsilon = 0.0M) { - if (x < 0) throw new OverflowException("Cannot calculate square root from a negative number"); + if (x < 0) + { + throw new OverflowException("Cannot calculate square root from a negative number"); + } decimal current = (decimal)Math.Sqrt((double)x), previous; do { previous = current; - if (previous == 0.0M) return 0; + if (previous == 0.0M) + { + return 0; + } + current = (previous + (x / previous)) / 2; } while (Math.Abs(previous - current) > epsilon); diff --git a/src/DynamicData/Aggregation/SumEx.cs b/src/DynamicData/Aggregation/SumEx.cs index c9997742d..71c2fe205 100644 --- a/src/DynamicData/Aggregation/SumEx.cs +++ b/src/DynamicData/Aggregation/SumEx.cs @@ -240,21 +240,8 @@ public static IObservable Sum(this IObservable> source, /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0, valueSelector, (current, value) => current + value, (current, value) => current - value); } @@ -277,21 +264,8 @@ public static IObservable Sum(this IObservable> s /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0, valueSelector, (current, value) => current + value, (current, value) => current - value); } @@ -305,21 +279,8 @@ public static IObservable Sum(this IObservable> /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0L, t => valueSelector(t).ValueOr(0), (current, value) => current + value, (current, value) => current - value); } @@ -333,21 +294,8 @@ public static IObservable Sum(this IObservable> /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0, valueSelector, (current, value) => current + value, (current, value) => current - value); } @@ -361,21 +309,8 @@ public static IObservable Sum(this IObservable /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0D, t => valueSelector(t).ValueOr(0), (current, value) => current + value, (current, value) => current - value); } @@ -389,21 +324,8 @@ public static IObservable Sum(this IObservable /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0, valueSelector, (current, value) => current + value, (current, value) => current - value); } @@ -417,21 +339,8 @@ public static IObservable Sum(this IObservableAn observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0M, t => valueSelector(t).ValueOr(0), (current, value) => current + value, (current, value) => current - value); } @@ -445,21 +354,8 @@ public static IObservable Sum(this IObservableAn observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0, valueSelector, (current, value) => current + value, (current, value) => current - value); } @@ -473,21 +369,8 @@ public static IObservable Sum(this IObservable> /// An observable which emits the summed value. public static IObservable Sum(this IObservable> source, Func valueSelector) { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(valueSelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.Accumulate(0F, t => valueSelector(t).ValueOr(0), (current, value) => current + value, (current, value) => current - value); } diff --git a/src/DynamicData/Alias/ObservableCacheAlias.cs b/src/DynamicData/Alias/ObservableCacheAlias.cs index c09232322..38b9c5aa3 100644 --- a/src/DynamicData/Alias/ObservableCacheAlias.cs +++ b/src/DynamicData/Alias/ObservableCacheAlias.cs @@ -25,7 +25,7 @@ public static class ObservableCacheAlias /// /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Select(this IObservable> source, Func transformFactory, IObservable forceTransform) @@ -33,20 +33,9 @@ public static IObservable> Select> Select /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Select(this IObservable> source, Func transformFactory, IObservable>? forceTransform = null) @@ -83,7 +72,7 @@ public static IObservable> Select /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Select(this IObservable> source, Func transformFactory, IObservable forceTransform) @@ -103,7 +92,7 @@ public static IObservable> Select /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Select(this IObservable> source, Func transformFactory, IObservable>? forceTransform = null) @@ -111,15 +100,8 @@ public static IObservable> Select> SelectMany< /// /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> SelectSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable forceTransform) @@ -165,25 +147,10 @@ public static IObservable> SelectSafe> SelectSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> SelectSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable>? forceTransform = null) @@ -212,20 +179,9 @@ public static IObservable> SelectSafe> SelectSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> SelectSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable>? forceTransform = null) @@ -254,20 +210,9 @@ public static IObservable> SelectSafe> SelectSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> SelectSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable forceTransform) @@ -308,15 +253,8 @@ public static IObservable, TKey>> SelectTree> Where(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Filter(filter); } @@ -353,15 +288,8 @@ public static IObservable> Where(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (predicateChanged is null) - { - throw new ArgumentNullException(nameof(predicateChanged)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + predicateChanged.ThrowArgumentNullExceptionIfNull(nameof(predicateChanged)); return source.Filter(predicateChanged); } @@ -378,15 +306,8 @@ public static IObservable> Where(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (reapplyFilter is null) - { - throw new ArgumentNullException(nameof(reapplyFilter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + reapplyFilter.ThrowArgumentNullExceptionIfNull(nameof(reapplyFilter)); return source.Filter(reapplyFilter); } @@ -404,20 +325,9 @@ public static IObservable> Where(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (predicateChanged is null) - { - throw new ArgumentNullException(nameof(predicateChanged)); - } - - if (reapplyFilter is null) - { - throw new ArgumentNullException(nameof(reapplyFilter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + predicateChanged.ThrowArgumentNullExceptionIfNull(nameof(predicateChanged)); + reapplyFilter.ThrowArgumentNullExceptionIfNull(nameof(reapplyFilter)); return source.Filter(predicateChanged, reapplyFilter); } diff --git a/src/DynamicData/Alias/ObservableListAlias.cs b/src/DynamicData/Alias/ObservableListAlias.cs index b430c7ef4..6eaaff295 100644 --- a/src/DynamicData/Alias/ObservableListAlias.cs +++ b/src/DynamicData/Alias/ObservableListAlias.cs @@ -17,7 +17,7 @@ public static class ObservableListAlias /// The source. /// The transform factory. /// An observable which emits the change set. - /// + /// /// source /// or /// valueSelector. @@ -26,15 +26,8 @@ public static IObservable> Select> SelectMany> SelectManyThe source. /// The valueSelector. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> Where(this IObservable> source, Func predicate) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + predicate.ThrowArgumentNullExceptionIfNull(nameof(predicate)); return source.Filter(predicate); } @@ -96,21 +75,14 @@ public static IObservable> Where(this IObservable /// The source. /// The predict for deciding on items to filter. /// An observable which emits the change set. - /// source + /// source /// or /// filterController. public static IObservable> Where(this IObservable> source, IObservable> predicate) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + predicate.ThrowArgumentNullExceptionIfNull(nameof(predicate)); return source.Filter(predicate); } diff --git a/src/DynamicData/Binding/BindingListAdaptor.cs b/src/DynamicData/Binding/BindingListAdaptor.cs index 8198e37dd..9fba1ad81 100644 --- a/src/DynamicData/Binding/BindingListAdaptor.cs +++ b/src/DynamicData/Binding/BindingListAdaptor.cs @@ -14,35 +14,23 @@ namespace DynamicData.Binding /// Adaptor to reflect a change set into a binding list. /// /// The type of items. - public class BindingListAdaptor : IChangeSetAdaptor + /// + /// Initializes a new instance of the class. + /// + /// The list of items to add to the adapter. + /// The threshold before a reset is issued. + public class BindingListAdaptor(BindingList list, int refreshThreshold = BindingOptions.DefaultResetThreshold) : IChangeSetAdaptor where T : notnull { - private readonly BindingList _list; - - private readonly int _refreshThreshold; - + private readonly BindingList _list = list ?? throw new ArgumentNullException(nameof(list)); private bool _loaded; - /// - /// Initializes a new instance of the class. - /// - /// The list of items to add to the adapter. - /// The threshold before a reset is issued. - public BindingListAdaptor(BindingList list, int refreshThreshold = BindingOptions.DefaultResetThreshold) - { - _list = list ?? throw new ArgumentNullException(nameof(list)); - _refreshThreshold = refreshThreshold; - } - /// public void Adapt(IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); - if (changes.TotalChanges - changes.Refreshes > _refreshThreshold || !_loaded) + if (changes.TotalChanges - changes.Refreshes > refreshThreshold || !_loaded) { using (new BindingListEventsSuspender(_list)) { @@ -62,36 +50,28 @@ public void Adapt(IChangeSet changes) /// /// The type of the object. /// The type of the key. + /// + /// Initializes a new instance of the class. + /// + /// The list of items to adapt. + /// The threshold before the refresh is triggered. [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Same class name, different generics")] - public class BindingListAdaptor : IChangeSetAdaptor + public class BindingListAdaptor(BindingList list, int refreshThreshold = BindingOptions.DefaultResetThreshold) : IChangeSetAdaptor where TObject : notnull where TKey : notnull { private readonly Cache _cache = new(); - private readonly BindingList _list; - - private readonly int _refreshThreshold; - + private readonly BindingList _list = list ?? throw new ArgumentNullException(nameof(list)); private bool _loaded; - /// - /// Initializes a new instance of the class. - /// - /// The list of items to adapt. - /// The threshold before the refresh is triggered. - public BindingListAdaptor(BindingList list, int refreshThreshold = BindingOptions.DefaultResetThreshold) - { - _list = list ?? throw new ArgumentNullException(nameof(list)); - _refreshThreshold = refreshThreshold; - } - /// public void Adapt(IChangeSet changes) { + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); _cache.Clone(changes); - if (changes.Count - changes.Refreshes > _refreshThreshold || !_loaded) + if (changes.Count - changes.Refreshes > refreshThreshold || !_loaded) { using (new BindingListEventsSuspender(_list)) { @@ -123,15 +103,23 @@ private static void DoUpdate(IChangeSet changes, BindingList= 0) + { list[previousIndex] = update.Current; + } else + { list.Add(update.Current); + } + break; case ChangeReason.Refresh: var index = list.IndexOf(update.Current); if (index != -1) + { list.ResetItem(index); + } + break; } } diff --git a/src/DynamicData/Binding/BindingListEventsSuspender.cs b/src/DynamicData/Binding/BindingListEventsSuspender.cs index 720ba21f8..fb2f9958b 100644 --- a/src/DynamicData/Binding/BindingListEventsSuspender.cs +++ b/src/DynamicData/Binding/BindingListEventsSuspender.cs @@ -24,11 +24,8 @@ public BindingListEventsSuspender(BindingList list) }); } - public void Dispose() - { - _cleanUp.Dispose(); - } + public void Dispose() => _cleanUp.Dispose(); } } -#endif \ No newline at end of file +#endif diff --git a/src/DynamicData/Binding/BindingListEx.cs b/src/DynamicData/Binding/BindingListEx.cs index 3addfa5d4..6c84b5e1f 100644 --- a/src/DynamicData/Binding/BindingListEx.cs +++ b/src/DynamicData/Binding/BindingListEx.cs @@ -14,12 +14,130 @@ namespace DynamicData.Binding; /// public static class BindingListEx { + /// + /// Observes list changed args. + /// + /// The source list. + /// An observable which emits event pattern changed event args. + public static IObservable> ObserveCollectionChanges(this IBindingList source) => + Observable.FromEventPattern(h => source.ListChanged += h, h => source.ListChanged -= h); + + /// + /// Convert a binding list into an observable change set. + /// Change set observes list change events. + /// + /// The type of the object. + /// The source. + /// An observable which emits change set values. + /// source. + public static IObservable> ToObservableChangeSet(this BindingList source) + where T : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + + return ToObservableChangeSet, T>(source); + } + + /// + /// Convert a binding list into an observable change set. + /// Change set observes list change events. + /// + /// The type of the object. + /// The type of the key. + /// The source. + /// The key selector. + /// An observable which emits change set values. + /// source + /// or + /// keySelector. + public static IObservable> ToObservableChangeSet(this BindingList source, Func keySelector) + where TObject : notnull + where TKey : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); + + return ToObservableChangeSet, TObject>(source).AddKey(keySelector); + } + + /// + /// Convert a binding list into an observable change set. + /// Change set observes list change events. + /// + /// The collection type. + /// The type of the object. + /// The source. + /// An observable which emits change set values. + /// source. + public static IObservable> ToObservableChangeSet(this TCollection source) + where TCollection : IBindingList, IEnumerable + where T : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + + return Observable.Create>( + observer => + { + var data = new ChangeAwareList(source); + + if (data.Count > 0) + { + observer.OnNext(data.CaptureChanges()); + } + + return source.ObserveCollectionChanges().Scan( + data, + (list, args) => + { + var changes = args.EventArgs; + + switch (changes.ListChangedType) + { + case ListChangedType.ItemAdded when source[changes.NewIndex] is T newItem: + { + if (changes.NewIndex == -1) + { + list.Add(newItem); + } + else + { + list.Insert(changes.NewIndex, newItem); + } + + break; + } + + case ListChangedType.ItemDeleted: + { + list.RemoveAt(changes.NewIndex); + break; + } + + case ListChangedType.ItemChanged when source[changes.NewIndex] is T newItem: + { + list[changes.NewIndex] = newItem; + break; + } + + case ListChangedType.Reset: + { + list.Clear(); + list.AddRange(source); + break; + } + } + + return list; + }).Select(list => list.CaptureChanges()).SubscribeSafe(observer); + }); + } + internal static void Clone(this BindingList source, IEnumerable> changes) where T : notnull { // ** Copied from ListEx for binding list specific changes - if (source is null) throw new ArgumentNullException(nameof(source)); - if (changes is null) throw new ArgumentNullException(nameof(changes)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); foreach (var item in changes) { @@ -96,7 +214,10 @@ private static void Clone(this BindingList source, Change item, IEquali { var index = source.IndexOf(item.Item.Current); if (index != -1) + { source.ResetItem(index); + } + break; } @@ -154,135 +275,4 @@ private static void Clone(this BindingList source, Change item, IEquali } } } - - /// - /// Observes list changed args. - /// - /// The source list. - /// An observable which emits event pattern changed event args. - public static IObservable> ObserveCollectionChanges(this IBindingList source) => - Observable.FromEventPattern(h => source.ListChanged += h, h => source.ListChanged -= h); - - /// - /// Convert a binding list into an observable change set. - /// Change set observes list change events. - /// - /// The type of the object. - /// The source. - /// An observable which emits change set values. - /// source. - public static IObservable> ToObservableChangeSet(this BindingList source) - where T : notnull - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return ToObservableChangeSet, T>(source); - } - - /// - /// Convert a binding list into an observable change set. - /// Change set observes list change events. - /// - /// The type of the object. - /// The type of the key. - /// The source. - /// The key selector. - /// An observable which emits change set values. - /// source - /// or - /// keySelector. - public static IObservable> ToObservableChangeSet(this BindingList source, Func keySelector) - where TObject : notnull - where TKey : notnull - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } - - return ToObservableChangeSet, TObject>(source).AddKey(keySelector); - } - - /// - /// Convert a binding list into an observable change set. - /// Change set observes list change events. - /// - /// The collection type. - /// The type of the object. - /// The source. - /// An observable which emits change set values. - /// source. - public static IObservable> ToObservableChangeSet(this TCollection source) - where TCollection : IBindingList, IEnumerable - where T : notnull - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return Observable.Create>( - observer => - { - var data = new ChangeAwareList(source); - - if (data.Count > 0) - { - observer.OnNext(data.CaptureChanges()); - } - - return source.ObserveCollectionChanges().Scan( - data, - (list, args) => - { - var changes = args.EventArgs; - - switch (changes.ListChangedType) - { - case ListChangedType.ItemAdded when source[changes.NewIndex] is T newItem: - { - if (changes.NewIndex == -1) - { - list.Add(newItem); - } - else - { - list.Insert(changes.NewIndex, newItem); - } - - break; - } - - case ListChangedType.ItemDeleted: - { - list.RemoveAt(changes.NewIndex); - break; - } - - case ListChangedType.ItemChanged when source[changes.NewIndex] is T newItem: - { - list[changes.NewIndex] = newItem; - break; - } - - case ListChangedType.Reset: - { - list.Clear(); - list.AddRange(source); - break; - } - } - - return list; - }).Select(list => list.CaptureChanges()).SubscribeSafe(observer); - }); - } } diff --git a/src/DynamicData/Binding/BindingOptions.cs b/src/DynamicData/Binding/BindingOptions.cs index dc823126f..75c78ad9c 100644 --- a/src/DynamicData/Binding/BindingOptions.cs +++ b/src/DynamicData/Binding/BindingOptions.cs @@ -8,8 +8,8 @@ namespace DynamicData.Binding; /// System wide default values for binding operators. /// /// The reset threshold ie the number of changes before a reset is fired. -/// Should a reset be fired for a first time load.This option is due to historic reasons where a reset would be fired for the first time load regardless of the number of changes. /// When possible, should replace be used instead of remove and add. +/// Should a reset be fired for a first time load.This option is due to historic reasons where a reset would be fired for the first time load regardless of the number of changes. public record struct BindingOptions(int ResetThreshold, bool UseReplaceForUpdates = BindingOptions.DefaultUseReplaceForUpdates, bool ResetOnFirstTimeLoad = BindingOptions.DefaultResetOnFirstTimeLoad) { /// @@ -32,15 +32,13 @@ public record struct BindingOptions(int ResetThreshold, bool UseReplaceForUpdate /// /// When possible, should replace be used instead of remove and add. /// The binding options. - public static BindingOptions NeverFireReset(bool useReplaceForUpdates = DefaultResetOnFirstTimeLoad) - { - return new BindingOptions(int.MaxValue, useReplaceForUpdates, false); - } + public static BindingOptions NeverFireReset(bool useReplaceForUpdates = DefaultResetOnFirstTimeLoad) => new(int.MaxValue, useReplaceForUpdates, false); } /// /// System wide default values for binding operators. /// +[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Related Files.")] public static class DynamicDataOptions { /// diff --git a/src/DynamicData/Binding/ExpressionBuilder.cs b/src/DynamicData/Binding/ExpressionBuilder.cs index 96373c0c9..4642dc69e 100644 --- a/src/DynamicData/Binding/ExpressionBuilder.cs +++ b/src/DynamicData/Binding/ExpressionBuilder.cs @@ -48,7 +48,7 @@ internal static Func CreateValueAccessor(this MemberExpression s if (method is null) { - throw new ArgumentException("The property does not have a valid get method.", nameof(source)); + throw new ArgumentException("The property does not have a valid get method.", nameof(method)); } if (source.Expression is null) diff --git a/src/DynamicData/Binding/IObservableListEx.cs b/src/DynamicData/Binding/IObservableListEx.cs index 3f6ee8919..bfb943804 100644 --- a/src/DynamicData/Binding/IObservableListEx.cs +++ b/src/DynamicData/Binding/IObservableListEx.cs @@ -22,7 +22,7 @@ public static class IObservableListEx /// The source. /// The output observable list. /// The change set for continued chaining. - /// source. + /// source. public static IObservable> BindToObservableList(this IObservable> source, out IObservableList observableList) where TObject : notnull { @@ -53,7 +53,7 @@ public static IObservable> BindToObservableList(thi /// The source. /// The observable list which is the output. /// The change set for continued chaining. - /// source. + /// source. public static IObservable> BindToObservableList(this IObservable> source, out IObservableList observableList) where TObject : notnull where TKey : notnull @@ -85,7 +85,7 @@ public static IObservable> BindToObservableListThe source. /// The output observable list. /// The change set for continued chaining. - /// source. + /// source. public static IObservable> BindToObservableList(this IObservable> source, out IObservableList observableList) where TObject : notnull where TKey : notnull diff --git a/src/DynamicData/Binding/NotifyPropertyChangedEx.cs b/src/DynamicData/Binding/NotifyPropertyChangedEx.cs index 8e6780e95..29fb6bf9d 100644 --- a/src/DynamicData/Binding/NotifyPropertyChangedEx.cs +++ b/src/DynamicData/Binding/NotifyPropertyChangedEx.cs @@ -23,10 +23,7 @@ public static class NotifyPropertyChangedEx public static IObservable WhenAnyPropertyChanged(this TObject source, params string[] propertiesToMonitor) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return Observable.FromEventPattern(handler => source.PropertyChanged += handler, handler => source.PropertyChanged -= handler).Where(x => propertiesToMonitor.Length == 0 || propertiesToMonitor.Contains(x.EventArgs.PropertyName)).Select(_ => source); } @@ -48,20 +45,9 @@ public static class NotifyPropertyChangedEx public static IObservable WhenChanged(this TObject source, Expression> p1, Func resultSelector, Func? p1Fallback = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (p1 is null) - { - throw new ArgumentNullException(nameof(p1)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + p1.ThrowArgumentNullExceptionIfNull(nameof(p1)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.WhenChanged(p1, true, p1Fallback).Select(v => resultSelector(source, v)); } @@ -86,25 +72,10 @@ public static class NotifyPropertyChangedEx public static IObservable WhenChanged(this TObject source, Expression> p1, Expression> p2, Func resultSelector, Func? p1Fallback = null, Func? p2Fallback = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (p1 is null) - { - throw new ArgumentNullException(nameof(p1)); - } - - if (p2 is null) - { - throw new ArgumentNullException(nameof(p2)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + p1.ThrowArgumentNullExceptionIfNull(nameof(p1)); + p2.ThrowArgumentNullExceptionIfNull(nameof(p2)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.WhenChanged(p1, true, p1Fallback).CombineLatest(source.WhenChanged(p2, true, p2Fallback), (v1, v2) => resultSelector(source, v1, v2)); } @@ -132,30 +103,11 @@ public static class NotifyPropertyChangedEx public static IObservable WhenChanged(this TObject source, Expression> p1, Expression> p2, Expression> p3, Func resultSelector, Func? p1Fallback = null, Func? p2Fallback = null, Func? p3Fallback = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (p1 is null) - { - throw new ArgumentNullException(nameof(p1)); - } - - if (p2 is null) - { - throw new ArgumentNullException(nameof(p2)); - } - - if (p3 is null) - { - throw new ArgumentNullException(nameof(p3)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + p1.ThrowArgumentNullExceptionIfNull(nameof(p1)); + p2.ThrowArgumentNullExceptionIfNull(nameof(p2)); + p3.ThrowArgumentNullExceptionIfNull(nameof(p3)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.WhenChanged(p1, true, p1Fallback).CombineLatest(source.WhenChanged(p2, true, p2Fallback), source.WhenChanged(p3, true, p3Fallback), (v1, v2, v3) => resultSelector(source, v1, v2, v3)); } @@ -186,35 +138,12 @@ public static class NotifyPropertyChangedEx public static IObservable WhenChanged(this TObject source, Expression> p1, Expression> p2, Expression> p3, Expression> p4, Func resultSelector, Func? p1Fallback = null, Func? p2Fallback = null, Func? p3Fallback = null, Func? p4Fallback = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (p1 is null) - { - throw new ArgumentNullException(nameof(p1)); - } - - if (p2 is null) - { - throw new ArgumentNullException(nameof(p2)); - } - - if (p3 is null) - { - throw new ArgumentNullException(nameof(p3)); - } - - if (p4 is null) - { - throw new ArgumentNullException(nameof(p4)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + p1.ThrowArgumentNullExceptionIfNull(nameof(p1)); + p2.ThrowArgumentNullExceptionIfNull(nameof(p2)); + p3.ThrowArgumentNullExceptionIfNull(nameof(p3)); + p4.ThrowArgumentNullExceptionIfNull(nameof(p4)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.WhenChanged(p1, true, p1Fallback).CombineLatest(source.WhenChanged(p2, true, p2Fallback), source.WhenChanged(p3, true, p3Fallback), source.WhenChanged(p4, true, p4Fallback), (v1, v2, v3, v4) => resultSelector(source, v1, v2, v3, v4)); } @@ -248,40 +177,13 @@ public static class NotifyPropertyChangedEx public static IObservable WhenChanged(this TObject source, Expression> p1, Expression> p2, Expression> p3, Expression> p4, Expression> p5, Func resultSelector, Func? p1Fallback = null, Func? p2Fallback = null, Func? p3Fallback = null, Func? p4Fallback = null, Func? p5Fallback = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (p1 is null) - { - throw new ArgumentNullException(nameof(p1)); - } - - if (p2 is null) - { - throw new ArgumentNullException(nameof(p2)); - } - - if (p3 is null) - { - throw new ArgumentNullException(nameof(p3)); - } - - if (p4 is null) - { - throw new ArgumentNullException(nameof(p4)); - } - - if (p5 is null) - { - throw new ArgumentNullException(nameof(p5)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + p1.ThrowArgumentNullExceptionIfNull(nameof(p1)); + p2.ThrowArgumentNullExceptionIfNull(nameof(p2)); + p3.ThrowArgumentNullExceptionIfNull(nameof(p3)); + p4.ThrowArgumentNullExceptionIfNull(nameof(p4)); + p5.ThrowArgumentNullExceptionIfNull(nameof(p5)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.WhenChanged(p1, true, p1Fallback).CombineLatest(source.WhenChanged(p2, true, p2Fallback), source.WhenChanged(p3, true, p3Fallback), source.WhenChanged(p4, true, p4Fallback), source.WhenChanged(p5, true, p5Fallback), (v1, v2, v3, v4, v5) => resultSelector(source, v1, v2, v3, v4, v5)); } @@ -318,45 +220,14 @@ public static class NotifyPropertyChangedEx public static IObservable WhenChanged(this TObject source, Expression> p1, Expression> p2, Expression> p3, Expression> p4, Expression> p5, Expression> p6, Func resultSelector, Func? p1Fallback = null, Func? p2Fallback = null, Func? p3Fallback = null, Func? p4Fallback = null, Func? p5Fallback = null, Func? p6Fallback = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (p1 is null) - { - throw new ArgumentNullException(nameof(p1)); - } - - if (p2 is null) - { - throw new ArgumentNullException(nameof(p2)); - } - - if (p3 is null) - { - throw new ArgumentNullException(nameof(p3)); - } - - if (p4 is null) - { - throw new ArgumentNullException(nameof(p4)); - } - - if (p5 is null) - { - throw new ArgumentNullException(nameof(p5)); - } - - if (p6 is null) - { - throw new ArgumentNullException(nameof(p6)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + p1.ThrowArgumentNullExceptionIfNull(nameof(p1)); + p2.ThrowArgumentNullExceptionIfNull(nameof(p2)); + p3.ThrowArgumentNullExceptionIfNull(nameof(p3)); + p4.ThrowArgumentNullExceptionIfNull(nameof(p4)); + p5.ThrowArgumentNullExceptionIfNull(nameof(p5)); + p6.ThrowArgumentNullExceptionIfNull(nameof(p6)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.WhenChanged(p1, true, p1Fallback).CombineLatest(source.WhenChanged(p2, true, p2Fallback), source.WhenChanged(p3, true, p3Fallback), source.WhenChanged(p4, true, p4Fallback), source.WhenChanged(p5, true, p5Fallback), source.WhenChanged(p6, true, p6Fallback), (v1, v2, v3, v4, v5, v6) => resultSelector(source, v1, v2, v3, v4, v5, v6)); } @@ -373,19 +244,12 @@ public static class NotifyPropertyChangedEx /// For example when observing Parent.Child.Age, if Child is null the value is unobtainable as Age is a struct and cannot be set to Null. /// For an object like Parent.Child.Sibling, sibling is an object so if Child is null, the value null and obtainable and is returned as null. /// A observable which also notifies when the property value changes. - /// propertyAccessor. + /// propertyAccessor. public static IObservable> WhenPropertyChanged(this TObject source, Expression> propertyAccessor, bool notifyOnInitialValue = true, Func? fallbackValue = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertyAccessor is null) - { - throw new ArgumentNullException(nameof(propertyAccessor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertyAccessor.ThrowArgumentNullExceptionIfNull(nameof(propertyAccessor)); var cache = ObservablePropertyFactoryCache.Instance.GetFactory(propertyAccessor); return cache.Create(source, notifyOnInitialValue).Where(pv => !pv.UnobtainableValue || (pv.UnobtainableValue && fallbackValue is not null)); @@ -406,15 +270,8 @@ public static IObservable> WhenPropertyChanged public static IObservable WhenValueChanged(this TObject source, Expression> propertyAccessor, bool notifyOnInitialValue = true, Func? fallbackValue = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertyAccessor is null) - { - throw new ArgumentNullException(nameof(propertyAccessor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertyAccessor.ThrowArgumentNullExceptionIfNull(nameof(propertyAccessor)); return source.WhenChanged(propertyAccessor, notifyOnInitialValue, fallbackValue); } diff --git a/src/DynamicData/Binding/ObservableCollectionAdaptor.cs b/src/DynamicData/Binding/ObservableCollectionAdaptor.cs index c5148639b..ace180b12 100644 --- a/src/DynamicData/Binding/ObservableCollectionAdaptor.cs +++ b/src/DynamicData/Binding/ObservableCollectionAdaptor.cs @@ -43,8 +43,8 @@ public ObservableCollectionAdaptor(IObservableCollection collection) /// /// Initializes a new instance of the class. /// - /// The binding options. /// The collection. + /// The binding options. public ObservableCollectionAdaptor(IObservableCollection collection, BindingOptions options) : this(collection, options.ResetThreshold, options.UseReplaceForUpdates, options.ResetOnFirstTimeLoad) { @@ -56,10 +56,7 @@ public ObservableCollectionAdaptor(IObservableCollection collection, BindingO /// The changes. public void Adapt(IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); if (changes.TotalChanges - changes.Refreshes > refreshThreshold || (!_loaded && resetOnFirstTimeLoad)) { @@ -113,15 +110,8 @@ public ObservableCollectionAdaptor(BindingOptions options) /// The collection. public void Adapt(IChangeSet changes, IObservableCollection collection) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } - - if (collection is null) - { - throw new ArgumentNullException(nameof(collection)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); + collection.ThrowArgumentNullExceptionIfNull(nameof(collection)); _cache.Clone(changes); diff --git a/src/DynamicData/Binding/ObservableCollectionEx.cs b/src/DynamicData/Binding/ObservableCollectionEx.cs index 938847ec9..d7fa41362 100644 --- a/src/DynamicData/Binding/ObservableCollectionEx.cs +++ b/src/DynamicData/Binding/ObservableCollectionEx.cs @@ -29,14 +29,11 @@ public static class ObservableCollectionEx /// The type of the object. /// The source. /// An observable that emits the change set. - /// source. + /// source. public static IObservable> ToObservableChangeSet(this ObservableCollection source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return ToObservableChangeSet, T>(source); } @@ -50,22 +47,15 @@ public static IObservable> ToObservableChangeSet(this Observabl /// The source. /// The key selector. /// An observable that emits the change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this ObservableCollection source, Func keySelector) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return ToObservableChangeSet, TObject>(source).AddKey(keySelector); } @@ -77,14 +67,11 @@ public static IObservable> ToObservableChangeSetThe type of the object. /// The source. /// An observable that emits the change set. - /// source. + /// source. public static IObservable> ToObservableChangeSet(this ReadOnlyObservableCollection source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return ToObservableChangeSet, T>(source); } @@ -98,22 +85,15 @@ public static IObservable> ToObservableChangeSet(this ReadOnlyO /// The source. /// The key selector. /// An observable that emits the change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this ReadOnlyObservableCollection source, Func keySelector) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return ToObservableChangeSet, TObject>(source).AddKey(keySelector); } @@ -126,16 +106,13 @@ public static IObservable> ToObservableChangeSetThe type of the object. /// The source. /// An observable that emits the change set. - /// source. + /// source. [System.Diagnostics.CodeAnalysis.SuppressMessage("Roslynator", "RCS1146:Use conditional access.", Justification = "net 7.0 has error when conditional access is used.")] public static IObservable> ToObservableChangeSet(this TCollection source) where TCollection : INotifyCollectionChanged, IEnumerable where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return Observable.Create>( observer => @@ -218,10 +195,14 @@ public static IObservable> ToObservableChangeSet(t case NotifyCollectionChangedAction.Move: if (changes.OldStartingIndex == -1) + { throw new UnspecifiedIndexException("Move -> OldStartingIndex"); + } if (changes.NewStartingIndex == -1) + { throw new UnspecifiedIndexException("Move -> NewStartingIndex"); + } list.Move(changes.OldStartingIndex, changes.NewStartingIndex); break; diff --git a/src/DynamicData/Binding/ObservableCollectionExtended.cs b/src/DynamicData/Binding/ObservableCollectionExtended.cs index 4fce4e4a9..399a818a2 100644 --- a/src/DynamicData/Binding/ObservableCollectionExtended.cs +++ b/src/DynamicData/Binding/ObservableCollectionExtended.cs @@ -51,10 +51,7 @@ public ObservableCollectionExtended(IEnumerable collection) /// is null. public void AddRange(IEnumerable collection) { - if (collection is null) - { - throw new ArgumentNullException(nameof(collection)); - } + collection.ThrowArgumentNullExceptionIfNull(nameof(collection)); foreach (var item in collection) { @@ -71,10 +68,7 @@ public void AddRange(IEnumerable collection) /// is less than 0.-or- is greater than Count. public void InsertRange(IEnumerable collection, int index) { - if (collection is null) - { - throw new ArgumentNullException(nameof(collection)); - } + collection.ThrowArgumentNullExceptionIfNull(nameof(collection)); foreach (var item in collection) { @@ -88,10 +82,7 @@ public void InsertRange(IEnumerable collection, int index) /// The items. public void Load(IEnumerable items) { - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + items.ThrowArgumentNullExceptionIfNull(nameof(items)); CheckReentrancy(); Clear(); @@ -173,10 +164,7 @@ protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) /// The instance containing the event data. protected override void OnPropertyChanged(PropertyChangedEventArgs e) { - if (e is null) - { - throw new ArgumentNullException(nameof(e)); - } + e.ThrowArgumentNullExceptionIfNull(nameof(e)); if (_suspendCount && e.PropertyName == "Count") { diff --git a/src/DynamicData/Binding/ObservablePropertyFactoryCache.cs b/src/DynamicData/Binding/ObservablePropertyFactoryCache.cs index c0bca0c20..1c4676518 100644 --- a/src/DynamicData/Binding/ObservablePropertyFactoryCache.cs +++ b/src/DynamicData/Binding/ObservablePropertyFactoryCache.cs @@ -27,21 +27,16 @@ public ObservablePropertyFactory GetFactory { - ObservablePropertyFactory factory; - var memberChain = expression.GetMemberChain().ToArray(); if (memberChain.Length == 1) { - factory = new ObservablePropertyFactory(expression); - } - else - { - var chain = memberChain.Select(m => new ObservablePropertyPart(m)).ToArray(); - var accessor = expression.Compile() ?? throw new ArgumentNullException(nameof(expression)); - factory = new ObservablePropertyFactory(accessor, chain); + return new ObservablePropertyFactory(expression); } - return factory; + var chain = memberChain.Select(m => new ObservablePropertyPart(m)).ToArray(); + var accessor = expression.Compile() ?? throw new ArgumentNullException(nameof(expression)); + + return new ObservablePropertyFactory(accessor, chain); }); return (ObservablePropertyFactory)result; diff --git a/src/DynamicData/Binding/PropertyValue.cs b/src/DynamicData/Binding/PropertyValue.cs index 67ce27b8a..1a6c33513 100644 --- a/src/DynamicData/Binding/PropertyValue.cs +++ b/src/DynamicData/Binding/PropertyValue.cs @@ -67,7 +67,7 @@ internal PropertyValue(TObject sender) /// public bool Equals(PropertyValue? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } diff --git a/src/DynamicData/Binding/SortedBindingListAdaptor.cs b/src/DynamicData/Binding/SortedBindingListAdaptor.cs index d6fd5cb3b..43b569f8f 100644 --- a/src/DynamicData/Binding/SortedBindingListAdaptor.cs +++ b/src/DynamicData/Binding/SortedBindingListAdaptor.cs @@ -13,32 +13,21 @@ namespace DynamicData.Binding /// /// The type of object. /// The type of key. - public class SortedBindingListAdaptor : ISortedChangeSetAdaptor + /// + /// Initializes a new instance of the class. + /// + /// The source list. + /// The threshold before a refresh is triggered. + public class SortedBindingListAdaptor(BindingList list, int refreshThreshold = 25) : ISortedChangeSetAdaptor where TObject : notnull where TKey : notnull { - private readonly BindingList _list; - - private readonly int _refreshThreshold; - - /// - /// Initializes a new instance of the class. - /// - /// The source list. - /// The threshold before a refresh is triggered. - public SortedBindingListAdaptor(BindingList list, int refreshThreshold = 25) - { - _list = list ?? throw new ArgumentNullException(nameof(list)); - _refreshThreshold = refreshThreshold; - } + private readonly BindingList _list = list ?? throw new ArgumentNullException(nameof(list)); /// public void Adapt(ISortedChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); switch (changes.SortedItems.SortReason) { @@ -54,7 +43,7 @@ public void Adapt(ISortedChangeSet changes) break; case SortReason.DataChanged: - if (changes.Count - changes.Refreshes > _refreshThreshold) + if (changes.Count - changes.Refreshes > refreshThreshold) { using (new BindingListEventsSuspender(_list)) { @@ -107,9 +96,13 @@ private void DoUpdate(ISortedChangeSet changes) { var previousIndex = _list.IndexOf(change.Previous.Value); if (previousIndex >= 0) + { _list[previousIndex] = change.Current; + } else + { _list.Add(change.Current); + } } break; @@ -117,7 +110,10 @@ private void DoUpdate(ISortedChangeSet changes) case ChangeReason.Refresh: var index = _list.IndexOf(change.Current); if (index != -1) + { _list.ResetItem(index); + } + break; } } diff --git a/src/DynamicData/Binding/SortedObservableCollectionAdaptor.cs b/src/DynamicData/Binding/SortedObservableCollectionAdaptor.cs index 54f8bfe68..c18fc964c 100644 --- a/src/DynamicData/Binding/SortedObservableCollectionAdaptor.cs +++ b/src/DynamicData/Binding/SortedObservableCollectionAdaptor.cs @@ -44,15 +44,8 @@ public SortedObservableCollectionAdaptor(BindingOptions options) /// The collection. public void Adapt(ISortedChangeSet changes, IObservableCollection collection) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } - - if (collection is null) - { - throw new ArgumentNullException(nameof(collection)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); + collection.ThrowArgumentNullExceptionIfNull(nameof(collection)); switch (changes.SortedItems.SortReason) { diff --git a/src/DynamicData/Cache/Change.cs b/src/DynamicData/Cache/Change.cs index 6bef43722..9a0037bdb 100644 --- a/src/DynamicData/Cache/Change.cs +++ b/src/DynamicData/Cache/Change.cs @@ -36,7 +36,7 @@ public Change(ChangeReason reason, TKey key, TObject current, int index = -1) /// The current. /// The CurrentIndex. /// CurrentIndex of the previous. - /// + /// /// CurrentIndex must be greater than or equal to zero /// or /// PreviousIndex must be greater than or equal to zero. @@ -71,12 +71,12 @@ public Change(TKey key, TObject current, int currentIndex, int previousIndex) /// The previous. /// Value of the current. /// Value of the previous. - /// + /// /// For ChangeReason.Add, a previous value cannot be specified /// or /// For ChangeReason.Change, must supply previous value. /// - public Change(ChangeReason reason, TKey key, TObject current, Optional previous, int currentIndex = -1, int previousIndex = -1) + public Change(ChangeReason reason, TKey key, TObject current, in Optional previous, int currentIndex = -1, int previousIndex = -1) : this() { Current = current; @@ -135,10 +135,7 @@ public Change(ChangeReason reason, TKey key, TObject current, Optional /// The left value to compare. /// The right value to compare. /// If the two values are equal to each other. - public static bool operator ==(Change left, Change right) - { - return left.Equals(right); - } + public static bool operator ==(in Change left, in Change right) => left.Equals(right); /// /// Determines whether the specified objects are equal. @@ -146,10 +143,7 @@ public Change(ChangeReason reason, TKey key, TObject current, Optional /// The left value to compare. /// The right value to compare. /// If the two values are not equal to each other. - public static bool operator !=(Change left, Change right) - { - return !left.Equals(right); - } + public static bool operator !=(in Change left, in Change right) => !left.Equals(right); /// public bool Equals(Change other) => EqualityComparer.Default.Equals(Key, other.Key) && Reason == other.Reason && EqualityComparer.Default.Equals(Current, other.Current) && CurrentIndex == other.CurrentIndex && Previous.Equals(other.Previous) && PreviousIndex == other.PreviousIndex; @@ -157,7 +151,7 @@ public Change(ChangeReason reason, TKey key, TObject current, Optional /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/Cache/ChangeAwareCache.cs b/src/DynamicData/Cache/ChangeAwareCache.cs index fe1a05103..77d2e6f8e 100644 --- a/src/DynamicData/Cache/ChangeAwareCache.cs +++ b/src/DynamicData/Cache/ChangeAwareCache.cs @@ -109,10 +109,7 @@ public void Clear() /// public void Clone(IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); foreach (var change in changes.ToConcreteType()) { @@ -147,10 +144,7 @@ public void Clone(IChangeSet changes) /// The keys to refresh. public void Refresh(IEnumerable keys) { - if (keys is null) - { - throw new ArgumentNullException(nameof(keys)); - } + keys.ThrowArgumentNullExceptionIfNull(nameof(keys)); if (keys is IList list) { @@ -191,10 +185,7 @@ public void Refresh(TKey key) /// The keys. public void Remove(IEnumerable keys) { - if (keys is null) - { - throw new ArgumentNullException(nameof(keys)); - } + keys.ThrowArgumentNullExceptionIfNull(nameof(keys)); if (keys is IList list) { diff --git a/src/DynamicData/Cache/ChangeSet.cs b/src/DynamicData/Cache/ChangeSet.cs index 1a1a961f5..27a1a6c58 100644 --- a/src/DynamicData/Cache/ChangeSet.cs +++ b/src/DynamicData/Cache/ChangeSet.cs @@ -17,7 +17,7 @@ public class ChangeSet : List>, IChangeSet< /// /// An empty change set. /// - public static readonly ChangeSet Empty = new(); + public static readonly ChangeSet Empty = []; /// /// Initializes a new instance of the class. diff --git a/src/DynamicData/Cache/GroupChangeSet.cs b/src/DynamicData/Cache/GroupChangeSet.cs index 4340552cd..f9a372e4b 100644 --- a/src/DynamicData/Cache/GroupChangeSet.cs +++ b/src/DynamicData/Cache/GroupChangeSet.cs @@ -10,7 +10,7 @@ internal sealed class GroupChangeSet : ChangeSet Empty = new GroupChangeSet(); + public static new readonly IGroupChangeSet Empty = new GroupChangeSet(); public GroupChangeSet(IEnumerable, TGroupKey>> items) : base(items) diff --git a/src/DynamicData/Cache/ICache.cs b/src/DynamicData/Cache/ICache.cs index 050154025..c248dc184 100644 --- a/src/DynamicData/Cache/ICache.cs +++ b/src/DynamicData/Cache/ICache.cs @@ -11,7 +11,7 @@ namespace DynamicData; /// /// The type of the object. /// The type of the key. -/// +/// public interface ICache : IQuery where TObject : notnull where TKey : notnull diff --git a/src/DynamicData/Cache/IChangeSetAdaptor.cs b/src/DynamicData/Cache/IChangeSetAdaptor.cs index 1e67a1550..e404a5553 100644 --- a/src/DynamicData/Cache/IChangeSetAdaptor.cs +++ b/src/DynamicData/Cache/IChangeSetAdaptor.cs @@ -17,6 +17,6 @@ public interface IChangeSetAdaptor /// /// Adapts the specified change. /// - /// The change. - void Adapt(IChangeSet change); + /// The change. + void Adapt(IChangeSet changes); } diff --git a/src/DynamicData/Cache/ISortedChangeSetAdaptor.cs b/src/DynamicData/Cache/ISortedChangeSetAdaptor.cs index 9511bc340..faa41b084 100644 --- a/src/DynamicData/Cache/ISortedChangeSetAdaptor.cs +++ b/src/DynamicData/Cache/ISortedChangeSetAdaptor.cs @@ -16,6 +16,6 @@ public interface ISortedChangeSetAdaptor /// /// Adapts the specified change. /// - /// The change. - void Adapt(ISortedChangeSet change); + /// The change. + void Adapt(ISortedChangeSet changes); } diff --git a/src/DynamicData/Cache/IndexedItem.cs b/src/DynamicData/Cache/IndexedItem.cs index c695a0693..bd1708d15 100644 --- a/src/DynamicData/Cache/IndexedItem.cs +++ b/src/DynamicData/Cache/IndexedItem.cs @@ -34,14 +34,25 @@ public sealed class IndexedItem(TObject value, TKey key, int inde public TObject Value { get; } = value; /// - public override bool Equals(object? obj) => obj is IndexedItem key && Equals(key); + public override bool Equals(object? obj) => obj is IndexedItem indexedKey && Equals(indexedKey); + + /// + public bool Equals(IndexedItem? other) + { + if (other is null) + { + return false; + } + + return EqualityComparer.Default.Equals(Key, other.Key) && EqualityComparer.Default.Equals(Value, other.Value) && Index == other.Index; + } /// public override int GetHashCode() { unchecked { - int hashCode = Key is null ? 0 : EqualityComparer.Default.GetHashCode(Key); + var hashCode = Key is null ? 0 : EqualityComparer.Default.GetHashCode(Key); hashCode = (hashCode * 397) ^ (Value is null ? 0 : EqualityComparer.Default.GetHashCode(Value)); hashCode = (hashCode * 397) ^ Index; return hashCode; @@ -50,15 +61,4 @@ public override int GetHashCode() /// public override string ToString() => $"Value: {Value}, Key: {Key}, CurrentIndex: {Index}"; - - /// - public bool Equals(IndexedItem? other) - { - if (other is null) - { - return false; - } - - return EqualityComparer.Default.Equals(Key, other.Key) && EqualityComparer.Default.Equals(Value, other.Value) && Index == other.Index; - } } diff --git a/src/DynamicData/Cache/IntermediateCache.cs b/src/DynamicData/Cache/IntermediateCache.cs index 769e38be3..d56f3b2e1 100644 --- a/src/DynamicData/Cache/IntermediateCache.cs +++ b/src/DynamicData/Cache/IntermediateCache.cs @@ -25,13 +25,10 @@ public sealed class IntermediateCache : IIntermediateCache class. /// /// The source. - /// source. + /// source. public IntermediateCache(IObservable> source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); _innerCache = new ObservableCache(source); } @@ -39,10 +36,7 @@ public IntermediateCache(IObservable> source) /// /// Initializes a new instance of the class. /// - public IntermediateCache() - { - _innerCache = new ObservableCache(); - } + public IntermediateCache() => _innerCache = new ObservableCache(); /// public int Count => _innerCache.Count; diff --git a/src/DynamicData/Cache/Internal/AbstractFilter.cs b/src/DynamicData/Cache/Internal/AbstractFilter.cs index 5fac8e86d..21b55590a 100644 --- a/src/DynamicData/Cache/Internal/AbstractFilter.cs +++ b/src/DynamicData/Cache/Internal/AbstractFilter.cs @@ -37,12 +37,9 @@ Optional> Factory(KeyValuePair kv) return new Change(ChangeReason.Add, kv.Key, kv.Value); } } - else + else if (existing.HasValue) { - if (existing.HasValue) - { - return new Change(ChangeReason.Remove, kv.Key, kv.Value, existing); - } + return new Change(ChangeReason.Remove, kv.Key, kv.Value, existing); } return Optional.None>(); @@ -118,12 +115,9 @@ private ChangeSet ProcessResult(IEnumerable sou _cache.Refresh(); } } - else + else if (existing.HasValue) { - if (existing.HasValue) - { - _cache.Remove(u.Key); - } + _cache.Remove(u.Key); } } diff --git a/src/DynamicData/Cache/Internal/AnonymousObservableCache.cs b/src/DynamicData/Cache/Internal/AnonymousObservableCache.cs index bf1faf0f7..5f4e49fe1 100644 --- a/src/DynamicData/Cache/Internal/AnonymousObservableCache.cs +++ b/src/DynamicData/Cache/Internal/AnonymousObservableCache.cs @@ -13,15 +13,13 @@ internal sealed class AnonymousObservableCache : IObservableCache where TObject : notnull where TKey : notnull { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed through _cleanUp")] private readonly IObservableCache _cache; private readonly IDisposable _cleanUp; public AnonymousObservableCache(IObservable> source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); _cache = new ObservableCache(source); diff --git a/src/DynamicData/Cache/Internal/BatchIf.cs b/src/DynamicData/Cache/Internal/BatchIf.cs index 5e907a753..d96678fef 100644 --- a/src/DynamicData/Cache/Internal/BatchIf.cs +++ b/src/DynamicData/Cache/Internal/BatchIf.cs @@ -76,17 +76,14 @@ IDisposable IntervalFunction() => ResumeAction(); } - else + else if (timeOut.HasValue) { - if (timeOut.HasValue) - { - timeoutDisposer.Disposable = Observable.Timer(timeOut.Value, _scheduler).Synchronize(locker).Subscribe( - _ => - { - paused = false; - ResumeAction(); - }); - } + timeoutDisposer.Disposable = Observable.Timer(timeOut.Value, _scheduler).Synchronize(locker).Subscribe( + _ => + { + paused = false; + ResumeAction(); + }); } }); diff --git a/src/DynamicData/Cache/Internal/Cache.cs b/src/DynamicData/Cache/Internal/Cache.cs index a52126980..7a6a62d9b 100644 --- a/src/DynamicData/Cache/Internal/Cache.cs +++ b/src/DynamicData/Cache/Internal/Cache.cs @@ -38,10 +38,7 @@ public Cache(int capacity = -1) => public void Clone(IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); foreach (var item in changes.ToConcreteType()) { diff --git a/src/DynamicData/Cache/Internal/CacheUpdater.cs b/src/DynamicData/Cache/Internal/CacheUpdater.cs index 4c05ea3b9..477cafd50 100644 --- a/src/DynamicData/Cache/Internal/CacheUpdater.cs +++ b/src/DynamicData/Cache/Internal/CacheUpdater.cs @@ -22,10 +22,7 @@ public CacheUpdater(ICache cache, Func? keySelecto public CacheUpdater(Dictionary data, Func? keySelector = null) { - if (data is null) - { - throw new ArgumentNullException(nameof(data)); - } + data.ThrowArgumentNullExceptionIfNull(nameof(data)); _cache = new Cache(data); _keySelector = keySelector; @@ -41,8 +38,12 @@ public CacheUpdater(Dictionary data, Func? keySele public void AddOrUpdate(IEnumerable items) { - if (items is null) throw new ArgumentNullException(nameof(items)); - if (_keySelector is null) throw new KeySelectorException("A key selector must be specified"); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); + + if (_keySelector is null) + { + throw new KeySelectorException("A key selector must be specified"); + } if (items is IList list) { @@ -63,9 +64,17 @@ public void AddOrUpdate(IEnumerable items) public void AddOrUpdate(IEnumerable items, IEqualityComparer comparer) { - if (items is null) throw new ArgumentNullException(nameof(items)); - if (comparer is null) throw new ArgumentNullException(nameof(comparer)); - if (_keySelector is null) throw new KeySelectorException("A key selector must be specified"); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); + + if (comparer is null) + { + throw new ArgumentNullException(nameof(comparer)); + } + + if (_keySelector is null) + { + throw new KeySelectorException("A key selector must be specified"); + } void AddOrUpdateImpl(TObject item) { @@ -74,7 +83,10 @@ void AddOrUpdateImpl(TObject item) if (oldItem.HasValue) { - if (comparer.Equals(oldItem.Value, item)) return; + if (comparer.Equals(oldItem.Value, item)) + { + return; + } _cache.AddOrUpdate(item, key); } @@ -88,12 +100,16 @@ void AddOrUpdateImpl(TObject item) { // zero allocation enumerator foreach (var item in EnumerableIList.Create(list)) + { AddOrUpdateImpl(item); + } } else { foreach (var item in items) + { AddOrUpdateImpl(item); + } } } @@ -195,10 +211,7 @@ public IEnumerable> GetKeyValues(IEnumerable items) { - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + items.ThrowArgumentNullExceptionIfNull(nameof(items)); Clear(); AddOrUpdate(items); @@ -225,10 +238,7 @@ public Optional Lookup(TObject item) public void Refresh(IEnumerable items) { - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + items.ThrowArgumentNullExceptionIfNull(nameof(items)); if (items is IList list) { @@ -249,10 +259,7 @@ public void Refresh(IEnumerable items) public void Refresh(IEnumerable keys) { - if (keys is null) - { - throw new ArgumentNullException(nameof(keys)); - } + keys.ThrowArgumentNullExceptionIfNull(nameof(keys)); if (keys is IList list) { @@ -286,10 +293,7 @@ public void Refresh(TObject item) public void Remove(IEnumerable items) { - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + items.ThrowArgumentNullExceptionIfNull(nameof(items)); if (items is IList list) { @@ -310,10 +314,7 @@ public void Remove(IEnumerable items) public void Remove(IEnumerable keys) { - if (keys is null) - { - throw new ArgumentNullException(nameof(keys)); - } + keys.ThrowArgumentNullExceptionIfNull(nameof(keys)); if (keys is IList list) { @@ -347,10 +348,7 @@ public void Remove(TObject item) public void Remove(IEnumerable> items) { - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + items.ThrowArgumentNullExceptionIfNull(nameof(items)); if (items is IList list) { @@ -375,10 +373,7 @@ public void Remove(IEnumerable> items) public void RemoveKeys(IEnumerable keys) { - if (keys is null) - { - throw new ArgumentNullException(nameof(keys)); - } + keys.ThrowArgumentNullExceptionIfNull(nameof(keys)); _cache.Remove(keys); } diff --git a/src/DynamicData/Cache/Internal/ChangeSetMergeTracker.cs b/src/DynamicData/Cache/Internal/ChangeSetMergeTracker.cs index 5a96d6ad5..55464e8e4 100644 --- a/src/DynamicData/Cache/Internal/ChangeSetMergeTracker.cs +++ b/src/DynamicData/Cache/Internal/ChangeSetMergeTracker.cs @@ -126,7 +126,7 @@ private void OnItemRemoved(ChangeSetCache[] sourceCaches, TObject } } - private void OnItemUpdated(ChangeSetCache[] sources, TObject item, TKey key, Optional prev) + private void OnItemUpdated(ChangeSetCache[] sources, TObject item, TKey key, in Optional prev) { var cached = _resultCache.Lookup(key); @@ -139,7 +139,7 @@ private void OnItemUpdated(ChangeSetCache[] sources, TObject item } // If the Previous value is missing or is the same as the current value - bool isUpdatingCurrent = !prev.HasValue || CheckEquality(prev.Value, cached.Value); + var isUpdatingCurrent = !prev.HasValue || CheckEquality(prev.Value, cached.Value); if (comparer is null) { @@ -204,7 +204,7 @@ private void ForceEvaluate(ChangeSetCache[] sources, TKey key) UpdateToBestValue(sources, key, cached); } - private bool UpdateToBestValue(ChangeSetCache[] sources, TKey key, Optional current) + private bool UpdateToBestValue(ChangeSetCache[] sources, TKey key, in Optional current) { // Determine which value should be the one seen downstream var candidate = LookupBestValue(sources, key); diff --git a/src/DynamicData/Cache/Internal/Combiner.cs b/src/DynamicData/Cache/Internal/Combiner.cs index 0739e17d6..98d7cb2de 100644 --- a/src/DynamicData/Cache/Internal/Combiner.cs +++ b/src/DynamicData/Cache/Internal/Combiner.cs @@ -61,8 +61,8 @@ private bool MatchesConstraint(TKey key) case CombineOperator.Except: { - bool first = _sourceCaches.Take(1).Any(s => s.Lookup(key).HasValue); - bool others = _sourceCaches.Skip(1).Any(s => s.Lookup(key).HasValue); + var first = _sourceCaches.Take(1).Any(s => s.Lookup(key).HasValue); + var others = _sourceCaches.Skip(1).Any(s => s.Lookup(key).HasValue); return first && !others; } @@ -90,12 +90,12 @@ private void Update(Cache cache, IChangeSet update } } - private IChangeSet UpdateCombined(IChangeSet updates) + private ChangeSet UpdateCombined(IChangeSet updates) { // child caches have been updated before we reached this point. foreach (var update in updates.ToConcreteType()) { - TKey key = update.Key; + var key = update.Key; switch (update.Reason) { case ChangeReason.Add: @@ -121,12 +121,9 @@ private IChangeSet UpdateCombined(IChangeSet updat _combinedCache.AddOrUpdate(update.Current, key); } } - else + else if (contained) { - if (contained) - { - _combinedCache.Remove(key); - } + _combinedCache.Remove(key); } } @@ -136,7 +133,7 @@ private IChangeSet UpdateCombined(IChangeSet updat { var cached = _combinedCache.Lookup(key); var contained = cached.HasValue; - bool shouldBeIncluded = MatchesConstraint(key); + var shouldBeIncluded = MatchesConstraint(key); if (shouldBeIncluded) { @@ -151,12 +148,9 @@ private IChangeSet UpdateCombined(IChangeSet updat _combinedCache.AddOrUpdate(firstOne, key); } } - else + else if (contained) { - if (contained) - { - _combinedCache.Remove(key); - } + _combinedCache.Remove(key); } } diff --git a/src/DynamicData/Cache/Internal/DeferUntilLoaded.cs b/src/DynamicData/Cache/Internal/DeferUntilLoaded.cs index bc1608a4e..b28059cd7 100644 --- a/src/DynamicData/Cache/Internal/DeferUntilLoaded.cs +++ b/src/DynamicData/Cache/Internal/DeferUntilLoaded.cs @@ -16,18 +16,12 @@ internal class DeferUntilLoaded public DeferUntilLoaded(IObservableCache source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); _result = source.CountChanged.Where(count => count != 0).Take(1).Select(_ => new ChangeSet()).Concat(source.Connect()).NotEmpty(); } - public DeferUntilLoaded(IObservable> source) - { - _result = source.MonitorStatus().Where(status => status == ConnectionStatus.Loaded).Take(1).Select(_ => new ChangeSet()).Concat(source).NotEmpty(); - } + public DeferUntilLoaded(IObservable> source) => _result = source.MonitorStatus().Where(status => status == ConnectionStatus.Loaded).Take(1).Select(_ => new ChangeSet()).Concat(source).NotEmpty(); public IObservable> Run() => _result; } diff --git a/src/DynamicData/Cache/Internal/DictionaryExtensions.cs b/src/DynamicData/Cache/Internal/DictionaryExtensions.cs index 3904f4456..651733ff4 100644 --- a/src/DynamicData/Cache/Internal/DictionaryExtensions.cs +++ b/src/DynamicData/Cache/Internal/DictionaryExtensions.cs @@ -6,13 +6,6 @@ namespace DynamicData.Cache.Internal; internal static class DictionaryExtensions { - internal static IEnumerable GetOrEmpty(this IDictionary> dict, TDictKey key) - { - if (dict.TryGetValue(key, out var value)) - { - return value; - } - - return Enumerable.Empty(); - } + internal static IEnumerable GetOrEmpty(this IDictionary> dict, TDictKey key) => + dict.TryGetValue(key, out var value) ? value : Enumerable.Empty(); } diff --git a/src/DynamicData/Cache/Internal/DisposeMany.cs b/src/DynamicData/Cache/Internal/DisposeMany.cs index b13b388b5..fb8a9cd04 100644 --- a/src/DynamicData/Cache/Internal/DisposeMany.cs +++ b/src/DynamicData/Cache/Internal/DisposeMany.cs @@ -33,7 +33,10 @@ public IObservable> Run() { case ChangeReason.Update: if (change.Previous.HasValue && !EqualityComparer.Default.Equals(change.Current, change.Previous.Value)) + { (change.Previous.Value as IDisposable)?.Dispose(); + } + break; case ChangeReason.Remove: @@ -62,14 +65,18 @@ public IObservable> Run() sourceSubscription.Dispose(); lock (cachedItems) + { ProcessFinalization(cachedItems); + } }); }); private static void ProcessFinalization(Dictionary cachedItems) { foreach (var pair in cachedItems) + { (pair.Value as IDisposable)?.Dispose(); + } cachedItems.Clear(); } diff --git a/src/DynamicData/Cache/Internal/DistinctCalculator.cs b/src/DynamicData/Cache/Internal/DistinctCalculator.cs index 61ae45a06..7aa38400d 100644 --- a/src/DynamicData/Cache/Internal/DistinctCalculator.cs +++ b/src/DynamicData/Cache/Internal/DistinctCalculator.cs @@ -13,10 +13,10 @@ internal sealed class DistinctCalculator(IObservable _itemCache = new Dictionary(); + private readonly Dictionary _itemCache = []; - private readonly IDictionary _keyCounters = new Dictionary(); - private readonly IDictionary _valueCounters = new Dictionary(); + private readonly Dictionary _keyCounters = []; + private readonly Dictionary _valueCounters = []; private readonly Func _valueSelector = valueSelector ?? throw new ArgumentNullException(nameof(valueSelector)); diff --git a/src/DynamicData/Cache/Internal/DynamicCombiner.cs b/src/DynamicData/Cache/Internal/DynamicCombiner.cs index e289b80ee..60514efc5 100644 --- a/src/DynamicData/Cache/Internal/DynamicCombiner.cs +++ b/src/DynamicData/Cache/Internal/DynamicCombiner.cs @@ -110,8 +110,8 @@ private bool MatchesConstraint(MergeContainer[] sources, TKey key) case CombineOperator.Except: { - bool first = sources.Take(1).Any(s => s.Cache.Lookup(key).HasValue); - bool others = sources.Skip(1).Any(s => s.Cache.Lookup(key).HasValue); + var first = sources.Take(1).Any(s => s.Cache.Lookup(key).HasValue); + var others = sources.Skip(1).Any(s => s.Cache.Lookup(key).HasValue); return first && !others; } @@ -156,12 +156,9 @@ private void ProcessItem(ChangeAwareCache target, MergeContainer[ target.AddOrUpdate(item, key); } } - else + else if (cached.HasValue) { - if (cached.HasValue) - { - target.Remove(key); - } + target.Remove(key); } } @@ -173,12 +170,9 @@ private void UpdateResultList(ChangeAwareCache target, MergeConta } } - private class MergeContainer + private sealed class MergeContainer { - public MergeContainer(IObservable> source) - { - Source = source.Do(Clone); - } + public MergeContainer(IObservable> source) => Source = source.Do(Clone); public Cache Cache { get; } = new(); diff --git a/src/DynamicData/Cache/Internal/DynamicFilter.cs b/src/DynamicData/Cache/Internal/DynamicFilter.cs index 2028962a4..c75cb7401 100644 --- a/src/DynamicData/Cache/Internal/DynamicFilter.cs +++ b/src/DynamicData/Cache/Internal/DynamicFilter.cs @@ -47,11 +47,13 @@ public IObservable> Run() => Observable.Create> LatestPredicateObservable() => Observable.Create>( @@ -61,7 +63,7 @@ private IObservable> LatestPredicateObservable() => Observab observable.OnNext(latest); - var predicateChanged = _predicateChanged.Subscribe( + var predicateChangedDisposable = _predicateChanged.Subscribe( predicate => { latest = predicate; @@ -70,6 +72,6 @@ private IObservable> LatestPredicateObservable() => Observab var reapplier = refilterObservable is null ? Disposable.Empty : refilterObservable.Subscribe(_ => observable.OnNext(latest)); - return new CompositeDisposable(predicateChanged, reapplier); + return new CompositeDisposable(predicateChangedDisposable, reapplier); }); } diff --git a/src/DynamicData/Cache/Internal/EditDiffChangeSetOptional.cs b/src/DynamicData/Cache/Internal/EditDiffChangeSetOptional.cs index 30ca56dae..702338e94 100644 --- a/src/DynamicData/Cache/Internal/EditDiffChangeSetOptional.cs +++ b/src/DynamicData/Cache/Internal/EditDiffChangeSetOptional.cs @@ -30,9 +30,9 @@ public IObservable> Run() => Observable.Create CreateUpdateChanges(previous.Value, current.Value), - (false, true) => new[] { new Change(ChangeReason.Add, current.Value.Key, current.Value.Object) }, - (true, false) => new[] { new Change(ChangeReason.Remove, previous.Value.Key, previous.Value.Object) }, - (false, false) => Array.Empty>(), + (false, true) => [new Change(ChangeReason.Add, current.Value.Key, current.Value.Object)], + (true, false) => [new Change(ChangeReason.Remove, previous.Value.Key, previous.Value.Object)], + (false, false) => [], }; // Save the value for the next round @@ -43,7 +43,9 @@ public IObservable> Run() => Observable.Create(changes)); } - }, observer.OnError, observer.OnCompleted); + }, + observer.OnError, + observer.OnCompleted); }); private Change[] CreateUpdateChanges(in ValueContainer prev, in ValueContainer curr) @@ -53,18 +55,18 @@ private Change[] CreateUpdateChanges(in ValueContainer prev, in V // Key is the same, so Update (unless values are equal) if (!_equalityComparer.Equals(prev.Object, curr.Object)) { - return new[] { new Change(ChangeReason.Update, curr.Key, curr.Object, prev.Object) }; + return [new Change(ChangeReason.Update, curr.Key, curr.Object, prev.Object)]; } - return Array.Empty>(); + return []; } // Key Change means Remove/Add - return new[] - { + return + [ new Change(ChangeReason.Remove, prev.Key, prev.Object), new Change(ChangeReason.Add, curr.Key, curr.Object) - }; + ]; } private readonly struct ValueContainer(TObject obj, TKey key) diff --git a/src/DynamicData/Cache/Internal/ExpirableItem.cs b/src/DynamicData/Cache/Internal/ExpirableItem.cs index 91674a05e..f2d0aef51 100644 --- a/src/DynamicData/Cache/Internal/ExpirableItem.cs +++ b/src/DynamicData/Cache/Internal/ExpirableItem.cs @@ -14,21 +14,15 @@ internal readonly struct ExpirableItem(TObject value, TKey key, D public long Index { get; } = index; - public static bool operator ==(ExpirableItem left, ExpirableItem right) - { - return left.Equals(right); - } + public static bool operator ==(in ExpirableItem left, in ExpirableItem right) => left.Equals(right); - public static bool operator !=(ExpirableItem left, ExpirableItem right) - { - return !left.Equals(right); - } + public static bool operator !=(in ExpirableItem left, in ExpirableItem right) => !left.Equals(right); /// public bool Equals(ExpirableItem other) => EqualityComparer.Default.Equals(Key, other.Key) && ExpireAt.Equals(other.ExpireAt); /// - public override bool Equals(object? obj) => obj is ExpirableItem value && Equals(value); + public override bool Equals(object? obj) => obj is ExpirableItem expItem && Equals(expItem); /// public override int GetHashCode() diff --git a/src/DynamicData/Cache/Internal/FilterEx.cs b/src/DynamicData/Cache/Internal/FilterEx.cs index 255a17a5d..6587fa1d4 100644 --- a/src/DynamicData/Cache/Internal/FilterEx.cs +++ b/src/DynamicData/Cache/Internal/FilterEx.cs @@ -91,12 +91,9 @@ public static IChangeSet RefreshFilteredFrom(this filtered.Add(kvp.Value, kvp.Key); } } - else + else if (existing.HasValue) { - if (existing.HasValue) - { - filtered.Remove(kvp.Key); - } + filtered.Remove(kvp.Key); } } diff --git a/src/DynamicData/Cache/Internal/FilterOnObservable.cs b/src/DynamicData/Cache/Internal/FilterOnObservable.cs index 0bde56f66..25d334628 100644 --- a/src/DynamicData/Cache/Internal/FilterOnObservable.cs +++ b/src/DynamicData/Cache/Internal/FilterOnObservable.cs @@ -19,7 +19,7 @@ internal class FilterOnObservable(IObservable proxy.PassesFilter) .Transform(proxy => proxy.Value); - private class FilterProxy + private sealed class FilterProxy { public FilterProxy(TObject obj, IObservable observable) { diff --git a/src/DynamicData/Cache/Internal/FilteredIndexCalculator.cs b/src/DynamicData/Cache/Internal/FilteredIndexCalculator.cs index 8a1a4aa4a..159efe8e1 100644 --- a/src/DynamicData/Cache/Internal/FilteredIndexCalculator.cs +++ b/src/DynamicData/Cache/Internal/FilteredIndexCalculator.cs @@ -31,7 +31,7 @@ public static IList> Calculate(IKeyValueCollection>(); foreach (var remove in removes) { - int index = previousList.IndexOf(remove); + var index = previousList.IndexOf(remove); previousList.RemoveAt(index); result.Add(new Change(ChangeReason.Remove, remove.Key, remove.Value, index)); @@ -40,8 +40,8 @@ public static IList> Calculate(IKeyValueCollection(ChangeReason.Add, add.Key, add.Value, insertIndex)); } @@ -62,8 +62,8 @@ public static IList> Calculate(IKeyValueCollection(ChangeReason.Update, current.Key, current.Value, previous.Value, insertIndex, removeIndex)); @@ -74,7 +74,7 @@ public static IList> Calculate(IKeyValueCollection(change.Key, change.Current); var previousIndex = previousList.IndexOf(current); - int desiredIndex = currentItems.IndexOf(current); + var desiredIndex = currentItems.IndexOf(current); if (previousIndex == desiredIndex) { @@ -112,7 +112,7 @@ public static IList> Calculate(IKeyValueCollection> Run() => Observable.Creat { foreach (var change in changes.ToConcreteType()) { - var left = change.Current; - var right = rightCache.Lookup(change.Key); + var leftCurrent = change.Current; + var rightLookup = rightCache.Lookup(change.Key); switch (change.Reason) { case ChangeReason.Add: case ChangeReason.Update: - joinedCache.AddOrUpdate(_resultSelector(change.Key, left, right), change.Key); + joinedCache.AddOrUpdate(_resultSelector(change.Key, leftCurrent, rightLookup), change.Key); break; case ChangeReason.Remove: - if (!right.HasValue) + if (!rightLookup.HasValue) { // remove from result because there is no left and no rights joinedCache.Remove(change.Key); @@ -60,7 +60,7 @@ public IObservable> Run() => Observable.Creat else { // update with no left value - joinedCache.AddOrUpdate(_resultSelector(change.Key, Optional.None, right), change.Key); + joinedCache.AddOrUpdate(_resultSelector(change.Key, Optional.None, rightLookup), change.Key); } break; diff --git a/src/DynamicData/Cache/Internal/GroupOn.cs b/src/DynamicData/Cache/Internal/GroupOn.cs index 76e9221f8..95ca6bd12 100644 --- a/src/DynamicData/Cache/Internal/GroupOn.cs +++ b/src/DynamicData/Cache/Internal/GroupOn.cs @@ -48,8 +48,8 @@ public IObservable> Run() => Observabl private sealed class Grouper(Func groupSelectorKey) { - private readonly Dictionary> _groupCache = new(); - private readonly Dictionary _itemCache = new(); + private readonly Dictionary> _groupCache = []; + private readonly Dictionary _itemCache = []; public IGroupChangeSet Regroup() { @@ -64,7 +64,9 @@ public IGroupChangeSet Regroup() { var cache = _groupCache.Lookup(key); if (cache.HasValue) + { return (cache.Value, false); + } var newcache = new ManagedGroup(key); _groupCache[key] = newcache; @@ -190,11 +192,7 @@ private GroupChangeSet HandleUpdates(IEnumerable - { - // must be created due to addition - groupUpdater.AddOrUpdate(current.Item, current.Key); - }); + () => groupUpdater.AddOrUpdate(current.Item, current.Key)); _itemCache[current.Key] = current; @@ -204,7 +202,11 @@ private GroupChangeSet HandleUpdates(IEnumerable, TGroupKey>(ChangeReason.Remove, @group.Key, groupCache)); }); @@ -222,15 +224,9 @@ private readonly struct ChangeWithGroup(Change change, Func left.Equals(right); - public static bool operator !=(ChangeWithGroup left, ChangeWithGroup right) - { - return !left.Equals(right); - } + public static bool operator !=(in ChangeWithGroup left, in ChangeWithGroup right) => !left.Equals(right); public bool Equals(ChangeWithGroup other) => EqualityComparer.Default.Equals(Key, other.Key); diff --git a/src/DynamicData/Cache/Internal/GroupOnImmutable.cs b/src/DynamicData/Cache/Internal/GroupOnImmutable.cs index 891a938f1..f6e6ec3a9 100644 --- a/src/DynamicData/Cache/Internal/GroupOnImmutable.cs +++ b/src/DynamicData/Cache/Internal/GroupOnImmutable.cs @@ -35,8 +35,8 @@ public IObservable> Run() => private sealed class Grouper(Func groupSelectorKey) { - private readonly IDictionary _allGroupings = new Dictionary(); - private readonly IDictionary _itemCache = new Dictionary(); + private readonly Dictionary _allGroupings = []; + private readonly Dictionary _itemCache = []; public IImmutableGroupChangeSet Regroup() { @@ -47,17 +47,17 @@ public IImmutableGroupChangeSet Regroup() public IImmutableGroupChangeSet Update(IChangeSet updates) => HandleUpdates(updates); - private static Exception CreateMissingKeyException(ChangeReason reason, TKey key) + private static MissingKeyException CreateMissingKeyException(ChangeReason reason, TKey key) { - var message = $"{key} is missing from previous group on {reason}." + $"{Environment.NewLine}Object type {typeof(TObject)}, Key type {typeof(TKey)}, Group key type {typeof(TGroupKey)}"; + var message = $"{key} is missing from previous group on {reason}.{Environment.NewLine}Object type {typeof(TObject)}, Key type {typeof(TKey)}, Group key type {typeof(TGroupKey)}"; return new MissingKeyException(message); } - private static IGrouping GetGroupState(GroupCache grouping) => new ImmutableGroup(grouping.Key, grouping.Cache); + private static ImmutableGroup GetGroupState(GroupCache grouping) => new(grouping.Key, grouping.Cache); - private static IGrouping GetGroupState(TGroupKey key, ICache cache) => new ImmutableGroup(key, cache); + private static ImmutableGroup GetGroupState(TGroupKey key, ICache cache) => new(key, cache); - private IImmutableGroupChangeSet CreateChangeSet(IDictionary> initialGroupState) + private ImmutableGroupChangeSet CreateChangeSet(IDictionary> initialGroupState) { var result = new List, TGroupKey>>(); foreach (var initialGroup in initialGroupState) @@ -101,7 +101,7 @@ private Tuple GetCache(TGroupKey key) return Tuple.Create(newcache, true); } - private IImmutableGroupChangeSet HandleUpdates(IEnumerable> changes) + private ImmutableGroupChangeSet HandleUpdates(IEnumerable> changes) { // need to keep track of effected groups to calculate correct notifications var initialStateOfGroups = new Dictionary>(); @@ -189,10 +189,7 @@ private IImmutableGroupChangeSet HandleUpdates(IEnumer cacheToModify.AddOrUpdate(current.Item, current.Key); }).Else( () => - { - // must be created due to addition - cacheToModify.AddOrUpdate(current.Item, current.Key); - }); + cacheToModify.AddOrUpdate(current.Item, current.Key)); // must be created due to addition _itemCache[current.Key] = current; break; @@ -205,7 +202,8 @@ private IImmutableGroupChangeSet HandleUpdates(IEnumer return CreateChangeSet(initialStateOfGroups); } - private void RemoveFromOldGroup(IDictionary> groupState, TGroupKey groupKey, TKey currentKey) => _allGroupings.Lookup(groupKey).IfHasValue( + private void RemoveFromOldGroup(Dictionary> groupState, TGroupKey groupKey, TKey currentKey) => + _allGroupings.Lookup(groupKey).IfHasValue( g => { if (!groupState.ContainsKey(g.Key)) @@ -226,15 +224,11 @@ private readonly struct ChangeWithGroup(Change change, Func + left.Equals(right); - public static bool operator !=(ChangeWithGroup left, ChangeWithGroup right) - { - return !left.Equals(right); - } + public static bool operator !=(in ChangeWithGroup left, in ChangeWithGroup right) => + !left.Equals(right); public bool Equals(ChangeWithGroup other) => Key.Equals(other.Key); @@ -245,7 +239,7 @@ private readonly struct ChangeWithGroup(Change change, Func $"Key: {Key}, GroupKey: {GroupKey}, Item: {Item}"; } - private class GroupCache(TGroupKey key) + private sealed class GroupCache(TGroupKey key) { public Cache Cache { get; } = new Cache(); diff --git a/src/DynamicData/Cache/Internal/ImmutableGroup.cs b/src/DynamicData/Cache/Internal/ImmutableGroup.cs index 0bdaea3da..c6573a371 100644 --- a/src/DynamicData/Cache/Internal/ImmutableGroup.cs +++ b/src/DynamicData/Cache/Internal/ImmutableGroup.cs @@ -11,7 +11,7 @@ internal sealed class ImmutableGroup : IGrouping _cache; + private readonly Cache _cache; internal ImmutableGroup(TGroupKey key, ICache cache) { @@ -30,15 +30,9 @@ internal ImmutableGroup(TGroupKey key, ICache cache) public IEnumerable> KeyValues => _cache.KeyValues; - public static bool operator ==(ImmutableGroup left, ImmutableGroup right) - { - return Equals(left, right); - } + public static bool operator ==(ImmutableGroup left, ImmutableGroup right) => Equals(left, right); - public static bool operator !=(ImmutableGroup left, ImmutableGroup right) - { - return !Equals(left, right); - } + public static bool operator !=(ImmutableGroup left, ImmutableGroup right) => !Equals(left, right); public bool Equals(ImmutableGroup? other) { diff --git a/src/DynamicData/Cache/Internal/IndexCalculator.cs b/src/DynamicData/Cache/Internal/IndexCalculator.cs index 67517c27d..8bf7b70b3 100644 --- a/src/DynamicData/Cache/Internal/IndexCalculator.cs +++ b/src/DynamicData/Cache/Internal/IndexCalculator.cs @@ -24,7 +24,7 @@ internal sealed class IndexCalculator(KeyValueComparer> Comparer => _comparer; - public List> List { get; private set; } = new List>(); + public List> List { get; private set; } = []; /// /// Dynamic calculation of moved items which produce a result which can be enumerated through in order. @@ -91,7 +91,7 @@ public IChangeSet Calculate(IChangeSet changes) if (evaluates.Count != 0 && optimisations.HasFlag(SortOptimisations.IgnoreEvaluates)) { // reorder entire sequence and do not calculate moves - List = List.OrderBy(kv => kv, _comparer).ToList(); + List = [.. List.OrderBy(kv => kv, _comparer)]; } else { @@ -106,7 +106,7 @@ public IChangeSet Calculate(IChangeSet changes) continue; } - int newPosition = GetInsertPositionLinear(List, current); + var newPosition = GetInsertPositionLinear(List, current); if (old < newPosition) { @@ -142,7 +142,7 @@ public IChangeSet Load(ChangeAwareCache cache) { // for the first batch of changes may have arrived before the comparer was set. // therefore infer the first batch of changes from the cache - List = cache.KeyValues.OrderBy(kv => kv, _comparer).ToList(); + List = [.. cache.KeyValues.OrderBy(kv => kv, _comparer)]; var initialItems = List.Select((t, index) => new Change(ChangeReason.Add, t.Key, t.Value, index)); return new ChangeSet(initialItems); } @@ -154,18 +154,18 @@ public IChangeSet Reorder() if (optimisations.HasFlag(SortOptimisations.IgnoreEvaluates)) { // reorder entire sequence and do not calculate moves - List = List.OrderBy(kv => kv, _comparer).ToList(); + List = [.. List.OrderBy(kv => kv, _comparer)]; } else { - int index = -1; + var index = -1; foreach (var item in List.OrderBy(t => t, _comparer).ToList()) { - KeyValuePair current = item; + var current = item; index++; // Cannot use binary search as Resort is implicit of a mutable change - KeyValuePair existing = List[index]; + var existing = List[index]; var areEqual = EqualityComparer.Default.Equals(current.Key, existing.Key); if (areEqual) { @@ -187,7 +187,7 @@ public IChangeSet Reorder() /// Initialises the specified changes. /// /// The cache. - public void Reset(ChangeAwareCache cache) => List = cache.KeyValues.OrderBy(kv => kv, _comparer).ToList(); + public void Reset(ChangeAwareCache cache) => List = [.. cache.KeyValues.OrderBy(kv => kv, _comparer)]; private int GetCurrentPosition(KeyValuePair item) { @@ -217,7 +217,7 @@ private int GetCurrentPosition(KeyValuePair item) private int GetInsertPositionBinary(KeyValuePair item) { - int index = List.BinarySearch(item, _comparer); + var index = List.BinarySearch(item, _comparer); if (index > 0) { diff --git a/src/DynamicData/Cache/Internal/InnerJoin.cs b/src/DynamicData/Cache/Internal/InnerJoin.cs index 3800da18e..155645a6c 100644 --- a/src/DynamicData/Cache/Internal/InnerJoin.cs +++ b/src/DynamicData/Cache/Internal/InnerJoin.cs @@ -41,24 +41,24 @@ internal class InnerJoin(IObse { foreach (var change in changes.ToConcreteType()) { - TLeft left = change.Current; - var right = rightGrouped.Lookup(change.Key); + var leftCurent = change.Current; + var rightLookup = rightGrouped.Lookup(change.Key); - if (right.HasValue) + if (rightLookup.HasValue) { switch (change.Reason) { case ChangeReason.Add: case ChangeReason.Update: - foreach (var keyvalue in right.Value.KeyValues) + foreach (var keyvalue in rightLookup.Value.KeyValues) { - joinedCache.AddOrUpdate(_resultSelector((change.Key, keyvalue.Key), left, keyvalue.Value), (change.Key, keyvalue.Key)); + joinedCache.AddOrUpdate(_resultSelector((change.Key, keyvalue.Key), leftCurent, keyvalue.Value), (change.Key, keyvalue.Key)); } break; case ChangeReason.Remove: - foreach (var keyvalue in right.Value.KeyValues) + foreach (var keyvalue in rightLookup.Value.KeyValues) { joinedCache.Remove((change.Key, keyvalue.Key)); } @@ -66,7 +66,7 @@ internal class InnerJoin(IObse break; case ChangeReason.Refresh: - foreach (var key in right.Value.Keys) + foreach (var key in rightLookup.Value.Keys) { joinedCache.Refresh((change.Key, key)); } diff --git a/src/DynamicData/Cache/Internal/KeyValueComparer.cs b/src/DynamicData/Cache/Internal/KeyValueComparer.cs index cae9a83f6..fd629e895 100644 --- a/src/DynamicData/Cache/Internal/KeyValueComparer.cs +++ b/src/DynamicData/Cache/Internal/KeyValueComparer.cs @@ -10,7 +10,7 @@ public int Compare(KeyValuePair x, KeyValuePair y) { if (comparer is not null) { - int result = comparer.Compare(x.Value, y.Value); + var result = comparer.Compare(x.Value, y.Value); if (result != 0) { diff --git a/src/DynamicData/Cache/Internal/LeftJoin.cs b/src/DynamicData/Cache/Internal/LeftJoin.cs index 909453a11..c6ffa9a1a 100644 --- a/src/DynamicData/Cache/Internal/LeftJoin.cs +++ b/src/DynamicData/Cache/Internal/LeftJoin.cs @@ -46,9 +46,9 @@ public IObservable> Run() => Observable.Creat case ChangeReason.Add: case ChangeReason.Update: // Update with left (and right if it is presents) - var left = change.Current; - var right = rightCache.Lookup(change.Key); - joined.AddOrUpdate(_resultSelector(change.Key, left, right), change.Key); + var leftCurrent = change.Current; + var rightLookup = rightCache.Lookup(change.Key); + joined.AddOrUpdate(_resultSelector(change.Key, leftCurrent, rightLookup), change.Key); break; case ChangeReason.Remove: diff --git a/src/DynamicData/Cache/Internal/LockFreeObservableCache.cs b/src/DynamicData/Cache/Internal/LockFreeObservableCache.cs index af5caf8d4..6c468bb85 100644 --- a/src/DynamicData/Cache/Internal/LockFreeObservableCache.cs +++ b/src/DynamicData/Cache/Internal/LockFreeObservableCache.cs @@ -101,11 +101,11 @@ public IObservable> Connect(Func? predi if (predicate != null) { - changes = changes.Filter(predicate, suppressEmptyChangeSets); + return changes.Filter(predicate, suppressEmptyChangeSets); } else if (suppressEmptyChangeSets) { - changes = changes.NotEmpty(); + return changes.NotEmpty(); } return changes; diff --git a/src/DynamicData/Cache/Internal/ManagedGroup.cs b/src/DynamicData/Cache/Internal/ManagedGroup.cs index 71ede3394..f2c10ae84 100644 --- a/src/DynamicData/Cache/Internal/ManagedGroup.cs +++ b/src/DynamicData/Cache/Internal/ManagedGroup.cs @@ -27,7 +27,7 @@ internal sealed class ManagedGroup(TGroupKey groupKey) /// The to compare with the current . public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/Cache/Internal/MergeMany.cs b/src/DynamicData/Cache/Internal/MergeMany.cs index 3233f3c1d..4fcca76a6 100644 --- a/src/DynamicData/Cache/Internal/MergeMany.cs +++ b/src/DynamicData/Cache/Internal/MergeMany.cs @@ -24,10 +24,7 @@ public MergeMany(IObservable> source, Func> source, Func> observableSelector) { - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); _source = source ?? throw new ArgumentNullException(nameof(source)); _observableSelector = (t, _) => observableSelector(t); diff --git a/src/DynamicData/Cache/Internal/Page.cs b/src/DynamicData/Cache/Internal/Page.cs index 8f9732f94..ed07863d3 100644 --- a/src/DynamicData/Cache/Internal/Page.cs +++ b/src/DynamicData/Cache/Internal/Page.cs @@ -71,8 +71,8 @@ private int CalculatePages() return 1; } - int pages = _all.Count / _request.Size; - int overlap = _all.Count % _request.Size; + var pages = _all.Count / _request.Size; + var overlap = _all.Count % _request.Size; if (overlap == 0) { @@ -82,18 +82,18 @@ private int CalculatePages() return pages + 1; } - private IPagedChangeSet? Paginate(ISortedChangeSet? updates = null) + private PagedChangeSet? Paginate(ISortedChangeSet? updates = null) { - if (_isLoaded == false) + if (!_isLoaded) { return null; } var previous = _current; - int pages = CalculatePages(); - int page = _request.Page > pages ? pages : _request.Page; - int skip = _request.Size * (page - 1); + var pages = CalculatePages(); + var page = _request.Page > pages ? pages : _request.Page; + var skip = _request.Size * (page - 1); var paged = _all.Skip(skip).Take(_request.Size).ToList(); diff --git a/src/DynamicData/Cache/Internal/ReaderWriter.cs b/src/DynamicData/Cache/Internal/ReaderWriter.cs index 4b036f23a..ab66d42ee 100644 --- a/src/DynamicData/Cache/Internal/ReaderWriter.cs +++ b/src/DynamicData/Cache/Internal/ReaderWriter.cs @@ -14,7 +14,7 @@ internal sealed class ReaderWriter(Func? keySelect private CacheUpdater? _activeUpdater; - private Dictionary _data = new(); // could do with priming this on first time load + private Dictionary _data = []; // could do with priming this on first time load public int Count { @@ -33,7 +33,7 @@ public TObject[] Items { lock (_locker) { - TObject[] result = new TObject[_data.Count]; + var result = new TObject[_data.Count]; _data.Values.CopyTo(result, 0); return result; } @@ -46,7 +46,7 @@ public TKey[] Keys { lock (_locker) { - TKey[] result = new TKey[_data.Count]; + var result = new TKey[_data.Count]; _data.Keys.CopyTo(result, 0); return result; } @@ -59,8 +59,8 @@ public KeyValuePair[] KeyValues { lock (_locker) { - KeyValuePair[] result = new KeyValuePair[_data.Count]; - int i = 0; + var result = new KeyValuePair[_data.Count]; + var i = 0; foreach (var kvp in _data) { result[i] = kvp; @@ -80,10 +80,10 @@ public ChangeSet GetInitialUpdates(Func? filter = if (dictionary.Count == 0) { - return ChangeSet.Empty; + return []; } - var changes = filter is null ? new ChangeSet(dictionary.Count) : new ChangeSet(); + var changes = filter is null ? new ChangeSet(dictionary.Count) : []; foreach (var kvp in dictionary) { @@ -107,30 +107,21 @@ public Optional Lookup(TKey key) public ChangeSet Write(IChangeSet changes, Action>? previewHandler, bool collectChanges) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); return DoUpdate(updater => updater.Clone(changes), previewHandler, collectChanges); } public ChangeSet Write(Action> updateAction, Action>? previewHandler, bool collectChanges) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); return DoUpdate(updateAction, previewHandler, collectChanges); } public ChangeSet Write(Action> updateAction, Action>? previewHandler, bool collectChanges) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); return DoUpdate(updateAction, previewHandler, collectChanges); } @@ -185,7 +176,7 @@ private ChangeSet DoUpdate(Action> up updateAction(_activeUpdater); _activeUpdater = null; - return ChangeSet.Empty; + return []; } } } diff --git a/src/DynamicData/Cache/Internal/RightJoin.cs b/src/DynamicData/Cache/Internal/RightJoin.cs index 1f56f6c74..a08552fd8 100644 --- a/src/DynamicData/Cache/Internal/RightJoin.cs +++ b/src/DynamicData/Cache/Internal/RightJoin.cs @@ -50,9 +50,9 @@ public IObservable> Run() => Observable.Crea case ChangeReason.Add: case ChangeReason.Update: // Update with right (and right if it is presents) - var right = change.Current; - var left = leftCache.Lookup(leftKey); - joinedCache.AddOrUpdate(_resultSelector(change.Key, left, right), change.Key); + var rightCurrent = change.Current; + var leftLookup = leftCache.Lookup(leftKey); + joinedCache.AddOrUpdate(_resultSelector(change.Key, leftLookup, rightCurrent), change.Key); break; case ChangeReason.Remove: @@ -74,7 +74,7 @@ public IObservable> Run() => Observable.Crea { foreach (var change in changes.ToConcreteType()) { - TLeft left = change.Current; + var left = change.Current; var right = rightGrouped.Lookup(change.Key); if (right.HasValue) diff --git a/src/DynamicData/Cache/Internal/Sort.cs b/src/DynamicData/Cache/Internal/Sort.cs index 7f61a1e0a..ab4101617 100644 --- a/src/DynamicData/Cache/Internal/Sort.cs +++ b/src/DynamicData/Cache/Internal/Sort.cs @@ -59,7 +59,7 @@ public IObservable> Run() => Observable.Create result is not null).Select(x => x!).SubscribeSafe(observer); }); - private class Sorter(SortOptimisations optimisations, IComparer? comparer = null, int resetThreshold = -1) + private sealed class Sorter(SortOptimisations optimisations, IComparer? comparer = null, int resetThreshold = -1) { private readonly ChangeAwareCache _cache = new(); private IndexCalculator? _calculator; @@ -102,7 +102,7 @@ private class Sorter(SortOptimisations optimisations, IComparer? compar /// The sort reason. /// The changes. /// The sorted change set. - private ISortedChangeSet? DoSort(SortReason sortReason, IChangeSet? changes = null) + private SortedChangeSet? DoSort(SortReason sortReason, IChangeSet? changes = null) { if (changes is not null) { diff --git a/src/DynamicData/Cache/Internal/StaticFilter.cs b/src/DynamicData/Cache/Internal/StaticFilter.cs index f2fea8379..35c451ee0 100644 --- a/src/DynamicData/Cache/Internal/StaticFilter.cs +++ b/src/DynamicData/Cache/Internal/StaticFilter.cs @@ -14,7 +14,8 @@ public IObservable> Run() => Observable.Create? cache = null; - return source.Subscribe(changes => + return source.Subscribe( + changes => { cache ??= new ChangeAwareCache(changes.Count); @@ -22,8 +23,11 @@ public IObservable> Run() => Observable.Create public SubscribeMany(IObservable> source, Func subscriptionFactory) { - if (subscriptionFactory is null) - { - throw new ArgumentNullException(nameof(subscriptionFactory)); - } + subscriptionFactory.ThrowArgumentNullExceptionIfNull(nameof(subscriptionFactory)); _source = source ?? throw new ArgumentNullException(nameof(source)); _subscriptionFactory = (t, _) => subscriptionFactory(t); diff --git a/src/DynamicData/Cache/Internal/TimeExpirer.cs b/src/DynamicData/Cache/Internal/TimeExpirer.cs index da0ef4f2b..991638434 100644 --- a/src/DynamicData/Cache/Internal/TimeExpirer.cs +++ b/src/DynamicData/Cache/Internal/TimeExpirer.cs @@ -70,7 +70,7 @@ void RemovalAction() { var toRemove = autoRemover.KeyValues.Where(kv => kv.Value.ExpireAt <= scheduler.Now.UtcDateTime).ToList(); - observer.OnNext(toRemove.Select(kv => new KeyValuePair(kv.Key, kv.Value.Value)).ToList()); + observer.OnNext(toRemove.ConvertAll(kv => new KeyValuePair(kv.Key, kv.Value.Value))); } catch (Exception ex) { diff --git a/src/DynamicData/Cache/Internal/ToObservableChangeSet.cs b/src/DynamicData/Cache/Internal/ToObservableChangeSet.cs index fa301d8e4..842331bcb 100644 --- a/src/DynamicData/Cache/Internal/ToObservableChangeSet.cs +++ b/src/DynamicData/Cache/Internal/ToObservableChangeSet.cs @@ -154,16 +154,22 @@ public Subscription( if (items is IReadOnlyList itemsList) { for (var i = 0; i < itemsList.Count; ++i) + { HandleIncomingItem(itemsList[i], now, changeSet, ref hasExpirationQueueChanged); + } } else { foreach (var item in items) + { HandleIncomingItem(item, now, changeSet, ref hasExpirationQueueChanged); + } } if (hasExpirationQueueChanged) + { OnExpirationQueueChanged(); + } observer.OnNext(changeSet); } @@ -186,10 +192,16 @@ public Subscription( // If there are pending expirations scheduled, wait to complete the stream until they're done if (_expirationState is null or { Queue.Count: 0 }) + { observer.OnCompleted(); + } })); } + // Instead of using a dedicated _synchronizationGate object, we can save an allocation by using any object that is never exposed to consumers. + private object SynchronizationGate + => _itemStatesByKey; + public void Dispose() { lock (SynchronizationGate) @@ -203,10 +215,6 @@ public void Dispose() private static int CompareExpireAtToExpiration(DateTimeOffset expireAt, Expiration expiration) => expireAt.CompareTo(expiration.ExpireAt); - // Instead of using a dedicated _synchronizationGate object, we can save an allocation by using any object that is never exposed to consumers. - private object SynchronizationGate - => _itemStatesByKey; - private void HandleIncomingItem( TObject item, DateTimeOffset now, @@ -223,7 +231,9 @@ private void HandleIncomingItem( { // Backwards compatibility if (evictionState.LimitSizeTo is 0) + { return; + } // Eviction is only applicable to adds, not replacements if (previousItemState is null) @@ -266,7 +276,9 @@ private void HandleIncomingItem( { var insertionIndex = expirationState.Queue.BinarySearch(expireAt.Value, CompareExpireAtToExpiration); if (insertionIndex < 0) + { insertionIndex = ~insertionIndex; + } expirationState.Queue.Insert( index: insertionIndex, @@ -310,7 +322,9 @@ private void HandleScheduledExpiration() foreach (var expiration in expirationState.Queue) { if (expiration.ExpireAt > now) + { break; + } ++processedExpirationCount; @@ -350,7 +364,9 @@ private void OnExpirationQueueChanged() if (expirationState.Queue.Count is 0) { if (_hasSourceCompleted) + { _observer.OnCompleted(); + } } else { diff --git a/src/DynamicData/Cache/Internal/ToObservableOptional.cs b/src/DynamicData/Cache/Internal/ToObservableOptional.cs index cd47c8d93..e849a5158 100644 --- a/src/DynamicData/Cache/Internal/ToObservableOptional.cs +++ b/src/DynamicData/Cache/Internal/ToObservableOptional.cs @@ -15,16 +15,19 @@ internal class ToObservableOptional(IObservable> Run() => Observable.Create>(observer => - _source.Subscribe(changes => + _source.Subscribe( + changes => changes.Where(ShouldEmitChange).ForEach(change => observer.OnNext(change switch { { Reason: ChangeReason.Remove } => Optional.None(), _ => Optional.Some(change.Current), - })), observer.OnError, observer.OnCompleted)); + })), + observer.OnError, + observer.OnCompleted)); private bool ShouldEmitChange(Change change) => change switch { - { Key: TKey key } when !key.Equals(_key) => false, + { Key: TKey thekey } when !thekey.Equals(_key) => false, { Reason: ChangeReason.Add } => true, { Reason: ChangeReason.Remove } => true, { Reason: ChangeReason.Update, Previous.HasValue: false } => true, diff --git a/src/DynamicData/Cache/Internal/TransformAsync.cs b/src/DynamicData/Cache/Internal/TransformAsync.cs index 306446c1c..6f0d69c2b 100644 --- a/src/DynamicData/Cache/Internal/TransformAsync.cs +++ b/src/DynamicData/Cache/Internal/TransformAsync.cs @@ -70,7 +70,7 @@ private async Task> DoTransform(ChangeAwareCache< return ProcessUpdates(cache, transformed); } - private IChangeSet ProcessUpdates(ChangeAwareCache cache, TransformResult[] transformedItems) + private ChangeSet ProcessUpdates(ChangeAwareCache cache, TransformResult[] transformedItems) { // check for errors and callback if a handler has been specified var errors = transformedItems.Where(t => !t.Success).ToArray(); @@ -81,7 +81,7 @@ private IChangeSet ProcessUpdates(ChangeAwareCache t.Success)) { - TKey key = result.Key; + var key = result.Key; switch (result.Change.Reason) { case ChangeReason.Add: @@ -138,7 +138,7 @@ private readonly struct TransformedItemContainer(TSource source, TDestination de private sealed class TransformResult { - public TransformResult(Change change, TransformedItemContainer container) + public TransformResult(in Change change, in TransformedItemContainer container) { Change = change; Container = container; @@ -146,7 +146,7 @@ public TransformResult(Change change, TransformedItemContainer co Key = change.Key; } - public TransformResult(Change change) + public TransformResult(in Change change) { Change = change; Container = Optional.None; @@ -154,7 +154,7 @@ public TransformResult(Change change) Key = change.Key; } - public TransformResult(Change change, Exception error) + public TransformResult(in Change change, Exception error) { Change = change; Error = error; diff --git a/src/DynamicData/Cache/Internal/TransformMany.cs b/src/DynamicData/Cache/Internal/TransformMany.cs index 5c1e5189d..bd5d8efb8 100644 --- a/src/DynamicData/Cache/Internal/TransformMany.cs +++ b/src/DynamicData/Cache/Internal/TransformMany.cs @@ -59,7 +59,8 @@ public TransformMany(IObservable> source, Func> source, Func> manySelector, Func keySelector) - : this(source, + : this( + source, x => manySelector(x).Items, keySelector, t => Observable.Defer( diff --git a/src/DynamicData/Cache/Internal/TransformWithForcedTransform.cs b/src/DynamicData/Cache/Internal/TransformWithForcedTransform.cs index 59f9ffc5c..116d2dd52 100644 --- a/src/DynamicData/Cache/Internal/TransformWithForcedTransform.cs +++ b/src/DynamicData/Cache/Internal/TransformWithForcedTransform.cs @@ -2,9 +2,9 @@ // Roland Pheasant licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using System.Linq; using System.Reactive.Disposables; using System.Reactive.Linq; - using DynamicData.Kernel; namespace DynamicData.Cache.Internal; @@ -35,14 +35,6 @@ public IObservable> Run() => Observable.Create> CaptureChanges(Cache cache, Func shouldTransform) - { - foreach (var kvp in cache.KeyValues) - { - if (shouldTransform(kvp.Value, kvp.Key)) - { - yield return new Change(ChangeReason.Refresh, kvp.Key, kvp.Value); - } - } - } + private static IEnumerable> CaptureChanges(Cache cache, Func shouldTransform) => + cache.KeyValues.Where(kvp => shouldTransform(kvp.Value, kvp.Key)).Select(kvp => new Change(ChangeReason.Refresh, kvp.Key, kvp.Value)); } diff --git a/src/DynamicData/Cache/Internal/TransformWithInlineUpdate.cs b/src/DynamicData/Cache/Internal/TransformWithInlineUpdate.cs index ae589bbfa..0d747a43a 100644 --- a/src/DynamicData/Cache/Internal/TransformWithInlineUpdate.cs +++ b/src/DynamicData/Cache/Internal/TransformWithInlineUpdate.cs @@ -55,7 +55,7 @@ private IObservable> RunImpl() => source.Scan( .Where(x => x is not null) .Select(cache => cache!.CaptureChanges()); - private void Transform(ChangeAwareCache cache, Change change) + private void Transform(ChangeAwareCache cache, in Change change) { TDestination transformed; if (exceptionCallback is not null) diff --git a/src/DynamicData/Cache/Internal/Virtualise.cs b/src/DynamicData/Cache/Internal/Virtualise.cs index a1b9c45fc..a0743ef14 100644 --- a/src/DynamicData/Cache/Internal/Virtualise.cs +++ b/src/DynamicData/Cache/Internal/Virtualise.cs @@ -58,7 +58,7 @@ private sealed class Virtualiser(VirtualRequest? request = null) return Virtualise(); } - private IVirtualChangeSet? Virtualise(ISortedChangeSet? updates = null) + private VirtualChangeSet? Virtualise(ISortedChangeSet? updates = null) { if (!_isLoaded) { diff --git a/src/DynamicData/Cache/Node.cs b/src/DynamicData/Cache/Node.cs index 675badf98..b1cce171f 100644 --- a/src/DynamicData/Cache/Node.cs +++ b/src/DynamicData/Cache/Node.cs @@ -19,9 +19,9 @@ public class Node : IDisposable, IEquatable> where TKey : notnull { [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed with _cleanUp")] - private readonly ISourceCache, TKey> _children = new SourceCache, TKey>(n => n.Key); + private readonly SourceCache, TKey> _children = new(n => n.Key); - private readonly IDisposable _cleanUp; + private readonly CompositeDisposable _cleanUp; private bool _isDisposed; @@ -41,13 +41,13 @@ public Node(TObject item, TKey key) /// The item. /// The key. /// The parent. - public Node(TObject item, TKey key, Optional> parent) + public Node(TObject item, TKey key, in Optional> parent) { Item = item ?? throw new ArgumentNullException(nameof(item)); Key = key; Parent = parent; Children = _children.AsObservableCache(); - _cleanUp = new CompositeDisposable(Children, _children); + _cleanUp = new(Children, _children); } /// @@ -64,17 +64,11 @@ public int Depth { var i = 0; var parent = Parent; - do + while (parent.HasValue) { - if (!parent.HasValue) - { - break; - } - i++; parent = parent.Value.Parent; } - while (true); return i; } @@ -109,10 +103,7 @@ public int Depth /// The left value to compare. /// The right value to compare. /// If the two values are equal. - public static bool operator ==(Node? left, Node? right) - { - return Equals(left, right); - } + public static bool operator ==(Node? left, Node? right) => Equals(left, right); /// /// Determines whether the specified objects are not equal. @@ -120,10 +111,7 @@ public int Depth /// The left value to compare. /// The right value to compare. /// If the two values are not equal. - public static bool operator !=(Node left, Node right) - { - return !Equals(left, right); - } + public static bool operator !=(Node left, Node right) => !Equals(left, right); /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// 2. @@ -139,7 +127,7 @@ public void Dispose() /// 2. public bool Equals(Node? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -158,7 +146,7 @@ public bool Equals(Node? other) /// 2. public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/Cache/ObservableCache.cs b/src/DynamicData/Cache/ObservableCache.cs index 9943b1ab7..b774cf031 100644 --- a/src/DynamicData/Cache/ObservableCache.cs +++ b/src/DynamicData/Cache/ObservableCache.cs @@ -163,10 +163,7 @@ public IObservable> Watch(TKey key) => internal void UpdateFromIntermediate(Action> updateAction) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); lock (_locker) { @@ -194,10 +191,7 @@ internal void UpdateFromIntermediate(Action> update internal void UpdateFromSource(Action> updateAction) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); lock (_locker) { diff --git a/src/DynamicData/Cache/ObservableCacheEx.cs b/src/DynamicData/Cache/ObservableCacheEx.cs index 2d7bcda13..267c6fe12 100644 --- a/src/DynamicData/Cache/ObservableCacheEx.cs +++ b/src/DynamicData/Cache/ObservableCacheEx.cs @@ -2,6 +2,7 @@ // Roland Pheasant licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; @@ -10,7 +11,7 @@ using System.Reactive.Concurrency; using System.Reactive.Disposables; using System.Reactive.Linq; - +using System.Transactions; using DynamicData.Binding; using DynamicData.Cache; using DynamicData.Cache.Internal; @@ -22,7 +23,6 @@ namespace DynamicData; /// /// Extensions for dynamic data. /// -[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "SA1137: Avoid different indentations", Justification = "Deliberate")] public static class ObservableCacheEx { private const int DefaultSortResetThreshold = 100; @@ -36,7 +36,7 @@ public static class ObservableCacheEx /// The source. /// The adaptor. /// An observable which will emit change sets. - /// + /// /// source /// or /// destination. @@ -45,15 +45,8 @@ public static IObservable> Adapt(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (adaptor is null) - { - throw new ArgumentNullException(nameof(adaptor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + adaptor.ThrowArgumentNullExceptionIfNull(nameof(adaptor)); return source.Do(adaptor.Adapt); } @@ -66,7 +59,7 @@ public static IObservable> Adapt(this I /// The source. /// The adaptor. /// An observable which will emit change sets. - /// + /// /// source /// or /// destination. @@ -75,15 +68,8 @@ public static IObservable> Adapt(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (adaptor is null) - { - throw new ArgumentNullException(nameof(adaptor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + adaptor.ThrowArgumentNullExceptionIfNull(nameof(adaptor)); return source.Do(adaptor.Adapt); } @@ -95,15 +81,12 @@ public static IObservable> Adapt(this I /// The type of the key. /// The source. /// The item. - /// source. + /// source. public static void AddOrUpdate(this ISourceCache source, TObject item) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.AddOrUpdate(item)); } @@ -116,15 +99,12 @@ public static void AddOrUpdate(this ISourceCache s /// The source. /// The item. /// The equality comparer used to determine whether a new item is the same as an existing cached item. - /// source. + /// source. public static void AddOrUpdate(this ISourceCache source, TObject item, IEqualityComparer equalityComparer) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.AddOrUpdate(item, equalityComparer)); } @@ -138,15 +118,12 @@ public static void AddOrUpdate(this ISourceCache s /// The type of the key. /// The source. /// The items. - /// source. + /// source. public static void AddOrUpdate(this ISourceCache source, IEnumerable items) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.AddOrUpdate(items)); } @@ -161,15 +138,12 @@ public static void AddOrUpdate(this ISourceCache s /// The source. /// The items. /// The equality comparer used to determine whether a new item is the same as an existing cached item. - /// source. + /// source. public static void AddOrUpdate(this ISourceCache source, IEnumerable items, IEqualityComparer equalityComparer) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.AddOrUpdate(items, equalityComparer)); } @@ -182,20 +156,13 @@ public static void AddOrUpdate(this ISourceCache s /// The source cache. /// The item to add or update. /// The key to add or update. - /// source. + /// source. public static void AddOrUpdate(this IIntermediateCache source, TObject item, TKey key) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (item is null) - { - throw new ArgumentNullException(nameof(item)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + item.ThrowArgumentNullExceptionIfNull(nameof(item)); source.Edit(updater => updater.AddOrUpdate(item, key)); } @@ -209,22 +176,16 @@ public static void AddOrUpdate(this IIntermediateCacheThe source. /// The others. /// An observable which emits change sets. - /// source or others. + /// source or others. public static IObservable> And(this IObservable> source, params IObservable>[] others) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (others is null || others.Length == 0) - { - throw new ArgumentNullException(nameof(others)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - return source.Combine(CombineOperator.And, others); + return others is null || others.Length == 0 + ? throw new ArgumentNullException(nameof(others)) + : source.Combine(CombineOperator.And, others); } /// @@ -234,7 +195,7 @@ public static IObservable> And(this IOb /// The type of the key. /// The source. /// An observable which emits change sets. - /// + /// /// source /// or /// others. @@ -243,10 +204,7 @@ public static IObservable> And(this ICo where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.And); } @@ -263,10 +221,7 @@ public static IObservable> And(this IOb where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.And); } @@ -283,10 +238,7 @@ public static IObservable> And(this IOb where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.And); } @@ -303,10 +255,7 @@ public static IObservable> And(this IOb where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.And); } @@ -318,15 +267,12 @@ public static IObservable> And(this IOb /// The type of the key. /// The source. /// An observable cache. - /// source. + /// source. public static IObservableCache AsObservableCache(this IObservableCache source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new AnonymousObservableCache(source); } @@ -339,15 +285,12 @@ public static IObservableCache AsObservableCache(t /// The source. /// if set to true all methods are synchronised. There is no need to apply locking when the consumer can be sure the read / write operations are already synchronised. /// An observable cache. - /// source. + /// source. public static IObservableCache AsObservableCache(this IObservable> source, bool applyLocking = true) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (applyLocking) { @@ -371,10 +314,7 @@ public static IObservable> AutoRefresh( where TObject : INotifyPropertyChanged where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.AutoRefreshOnObservable( (t, _) => @@ -406,10 +346,7 @@ public static IObservable> AutoRefresh @@ -455,15 +392,8 @@ public static IObservable> AutoRefreshOnObservable(source, reevaluator, changeSetBuffer, scheduler).Run(); } @@ -477,17 +407,14 @@ public static IObservable> AutoRefreshOnObservableThe time span. /// The scheduler. /// An observable which emits change sets. - /// source + /// source /// or /// scheduler. public static IObservable> Batch(this IObservable> source, TimeSpan timeSpan, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Buffer(timeSpan, scheduler ?? Scheduler.Default).FlattenBufferResult(); } @@ -502,7 +429,7 @@ public static IObservable> Batch(this I /// When true, observable begins to buffer and when false, window closes and buffered result if notified. /// The scheduler. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> BatchIf(this IObservable> source, IObservable pauseIfTrueSelector, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull => BatchIf(source, pauseIfTrueSelector, false, scheduler); @@ -518,7 +445,7 @@ public static IObservable> BatchIf(this /// if set to true [initial pause state]. /// The scheduler. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> BatchIf(this IObservable> source, IObservable pauseIfTrueSelector, bool initialPauseState = false, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull => new BatchIf(source, pauseIfTrueSelector, null, initialPauseState, scheduler: scheduler).Run(); @@ -534,7 +461,7 @@ public static IObservable> BatchIf(this /// Specify a time to ensure the buffer window does not stay open for too long. On completion buffering will cease. /// The scheduler. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> BatchIf(this IObservable> source, IObservable pauseIfTrueSelector, TimeSpan? timeOut = null, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull => BatchIf(source, pauseIfTrueSelector, false, timeOut, scheduler); @@ -551,20 +478,13 @@ public static IObservable> BatchIf(this /// Specify a time to ensure the buffer window does not stay open for too long. On completion buffering will cease. /// The scheduler. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> BatchIf(this IObservable> source, IObservable pauseIfTrueSelector, bool initialPauseState = false, TimeSpan? timeOut = null, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (pauseIfTrueSelector is null) - { - throw new ArgumentNullException(nameof(pauseIfTrueSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + pauseIfTrueSelector.ThrowArgumentNullExceptionIfNull(nameof(pauseIfTrueSelector)); return new BatchIf(source, pauseIfTrueSelector, timeOut, initialPauseState, scheduler: scheduler).Run(); } @@ -581,7 +501,7 @@ public static IObservable> BatchIf(this /// Specify a time observable. The buffer will be emptied each time the timer produces a value and when it completes. On completion buffering will cease. /// The scheduler. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> BatchIf(this IObservable> source, IObservable pauseIfTrueSelector, bool initialPauseState = false, IObservable? timer = null, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull => new BatchIf(source, pauseIfTrueSelector, null, initialPauseState, timer, scheduler).Run(); @@ -600,8 +520,7 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (destination is null) throw new ArgumentNullException(nameof(destination)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); // if user has not specified different defaults, use system wide defaults instead. // This is a hack to retro fit system wide defaults which override the hard coded defaults above @@ -611,7 +530,7 @@ public static IObservable> Bind(this IO ? defaults : defaults with { ResetThreshold = refreshThreshold }; - return source.Bind(destination, new ObservableCollectionAdaptor(options)); + return source?.Bind(destination, new ObservableCollectionAdaptor(options)) ?? throw new ArgumentNullException(nameof(source)); } /// @@ -628,10 +547,9 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (destination is null) throw new ArgumentNullException(nameof(destination)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); - return source.Bind(destination, new ObservableCollectionAdaptor(options)); + return source?.Bind(destination, new ObservableCollectionAdaptor(options)) ?? throw new ArgumentNullException(nameof(source)); } /// @@ -643,14 +561,14 @@ public static IObservable> Bind(this IO /// The destination. /// The updater. /// An observable which will emit change sets. - /// source. + /// source. public static IObservable> Bind(this IObservable> source, IObservableCollection destination, IObservableCollectionAdaptor updater) where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (destination is null) throw new ArgumentNullException(nameof(destination)); - if (updater is null) throw new ArgumentNullException(nameof(updater)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); + updater.ThrowArgumentNullExceptionIfNull(nameof(updater)); return Observable.Create>( observer => @@ -679,10 +597,7 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); var target = new ObservableCollectionExtended(); readOnlyObservableCollection = new ReadOnlyObservableCollection(target); @@ -705,10 +620,7 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (adaptor is not null) { @@ -736,13 +648,13 @@ public static IObservable> Bind(this IO /// The source. /// The destination. /// An observable which will emit change sets. - /// source. + /// source. public static IObservable> Bind(this IObservable> source, IObservableCollection destination) where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (destination is null) throw new ArgumentNullException(nameof(destination)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); return source.Bind(destination, DynamicDataOptions.Binding); } @@ -761,8 +673,8 @@ public static IObservable> Bind(t where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (destination is null) throw new ArgumentNullException(nameof(destination)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); var updater = new SortedObservableCollectionAdaptor(options); return source.Bind(destination, updater); @@ -777,14 +689,14 @@ public static IObservable> Bind(t /// The destination. /// The updater. /// An observable which will emit change sets. - /// source. + /// source. public static IObservable> Bind(this IObservable> source, IObservableCollection destination, ISortedObservableCollectionAdaptor updater) where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (destination is null) throw new ArgumentNullException(nameof(destination)); - if (updater is null) throw new ArgumentNullException(nameof(updater)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); + updater.ThrowArgumentNullExceptionIfNull(nameof(updater)); return Observable.Create>( observer => @@ -813,10 +725,7 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); var target = new ObservableCollectionExtended(); var result = new ReadOnlyObservableCollection(target); @@ -841,7 +750,7 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); // if user has not specified different defaults, use system wide defaults instead. // This is a hack to retro fit system wide defaults which override the hard coded defaults above @@ -868,7 +777,7 @@ public static IObservable> Bind(this IO /// The target binding list. /// The reset threshold. /// An observable which will emit change sets. - /// + /// /// source /// or /// targetCollection. @@ -877,15 +786,8 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (bindingList is null) - { - throw new ArgumentNullException(nameof(bindingList)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + bindingList.ThrowArgumentNullExceptionIfNull(nameof(bindingList)); return source.Adapt(new BindingListAdaptor(bindingList, resetThreshold)); } @@ -899,7 +801,7 @@ public static IObservable> Bind(this IO /// The target binding list. /// The reset threshold. /// An observable which will emit change sets. - /// + /// /// source /// or /// targetCollection. @@ -908,15 +810,8 @@ public static IObservable> Bind(this IO where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (bindingList is null) - { - throw new ArgumentNullException(nameof(bindingList)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + bindingList.ThrowArgumentNullExceptionIfNull(nameof(bindingList)); return source.Adapt(new SortedBindingListAdaptor(bindingList, resetThreshold)); } @@ -957,10 +852,7 @@ public static IObservable> Cast(source, converter).Run(); } @@ -979,15 +871,8 @@ public static IObservable> ChangeKey @@ -1006,21 +891,14 @@ public static IObservable> ChangeKeyThe source. /// The key selector eg. (key, item) => newKey. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> ChangeKey(this IObservable> source, Func keySelector) where TObject : notnull where TSourceKey : notnull where TDestinationKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return source.Select( updates => @@ -1036,15 +914,12 @@ public static IObservable> ChangeKeyThe type of the object. /// The type of the key. /// The source. - /// source. + /// source. public static void Clear(this ISourceCache source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Clear()); } @@ -1055,15 +930,12 @@ public static void Clear(this ISourceCache source) /// The type of the object. /// The type of the key. /// The source. - /// source. + /// source. public static void Clear(this IIntermediateCache source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Clear()); } @@ -1074,16 +946,12 @@ public static void Clear(this IIntermediateCache s /// The type of the object. /// The type of the key. /// The source. - /// source. + /// source. public static void Clear(this LockFreeObservableCache source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Clear()); } @@ -1099,15 +967,8 @@ public static IObservable> Clone(this I where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (target is null) - { - throw new ArgumentNullException(nameof(target)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + target.ThrowArgumentNullExceptionIfNull(nameof(target)); return source.Do( changes => @@ -1155,15 +1016,8 @@ public static IObservable> Convert @@ -1184,10 +1038,7 @@ public static IObservable> DeferUntilLoaded(source).Run(); } @@ -1203,10 +1054,7 @@ public static IObservable> DeferUntilLoaded(source).Run(); } @@ -1222,15 +1070,12 @@ public static IObservable> DeferUntilLoadedThe type of the key. /// The source. /// A continuation of the original stream. - /// source. + /// source. public static IObservable> DisposeMany(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new DisposeMany(source).Run(); } @@ -1247,21 +1092,14 @@ public static IObservable> DisposeMany( /// /// Due to it's nature only adds or removes can be returned. /// - /// source. + /// source. public static IObservable> DistinctValues(this IObservable> source, Func valueSelector) where TObject : notnull where TKey : notnull where TValue : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return Observable.Create>(observer => new DistinctCalculator(source, valueSelector).Run().SubscribeSafe(observer)); } @@ -1275,25 +1113,14 @@ public static IObservable> DistinctValuesThe source. /// The items to add, update or delete. /// The equality comparer used to determine whether a new item is the same as an existing cached item. - /// source. + /// source. public static void EditDiff(this ISourceCache source, IEnumerable allItems, IEqualityComparer equalityComparer) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (allItems is null) - { - throw new ArgumentNullException(nameof(allItems)); - } - - if (equalityComparer is null) - { - throw new ArgumentNullException(nameof(equalityComparer)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + allItems.ThrowArgumentNullExceptionIfNull(nameof(allItems)); + equalityComparer.ThrowArgumentNullExceptionIfNull(nameof(equalityComparer)); source.EditDiff(allItems, equalityComparer.Equals); } @@ -1307,25 +1134,14 @@ public static void EditDiff(this ISourceCache sour /// The source. /// The items to compare and add, update or delete. /// Expression to determine whether an item's value is equal to the old value (current, previous) => current.Version == previous.Version. - /// source. + /// source. public static void EditDiff(this ISourceCache source, IEnumerable allItems, Func areItemsEqual) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (allItems is null) - { - throw new ArgumentNullException(nameof(allItems)); - } - - if (areItemsEqual is null) - { - throw new ArgumentNullException(nameof(areItemsEqual)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + allItems.ThrowArgumentNullExceptionIfNull(nameof(allItems)); + areItemsEqual.ThrowArgumentNullExceptionIfNull(nameof(areItemsEqual)); var editDiff = new EditDiff(source, areItemsEqual); editDiff.Edit(allItems); @@ -1340,20 +1156,13 @@ public static void EditDiff(this ISourceCache sour /// Key Selection Function for the ChangeSet. /// Optional instance to use for comparing values. /// An observable cache. - /// source. + /// source. public static IObservable> EditDiff(this IObservable> source, Func keySelector, IEqualityComparer? equalityComparer = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return new EditDiffChangeSet(source, keySelector, equalityComparer).Run(); } @@ -1367,20 +1176,13 @@ public static IObservable> EditDiff(thi /// Key Selection Function for the ChangeSet. /// Optional instance to use for comparing values. /// An observable changeset. - /// source. + /// source. public static IObservable> EditDiff(this IObservable> source, Func keySelector, IEqualityComparer? equalityComparer = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return new EditDiffChangeSetOptional(source, keySelector, equalityComparer).Run(); } @@ -1392,16 +1194,13 @@ public static IObservable> EditDiff(thi /// The type of the key. /// The source. /// The item. - /// source. + /// source. [Obsolete(Constants.EvaluateIsDead)] public static void Evaluate(this ISourceCache source, TObject item) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Refresh(item)); } @@ -1413,16 +1212,13 @@ public static void Evaluate(this ISourceCache sour /// The type of the key. /// The source. /// The items. - /// source. + /// source. [Obsolete(Constants.EvaluateIsDead)] public static void Evaluate(this ISourceCache source, IEnumerable items) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Refresh(items)); } @@ -1433,16 +1229,13 @@ public static void Evaluate(this ISourceCache sour /// The type of the object. /// The type of the key. /// The source. - /// source. + /// source. [Obsolete(Constants.EvaluateIsDead)] public static void Evaluate(this ISourceCache source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Refresh()); } @@ -1456,7 +1249,7 @@ public static void Evaluate(this ISourceCache sour /// The source. /// The others. /// An observable which emits change sets. - /// + /// /// source /// or /// others. @@ -1465,10 +1258,7 @@ public static IObservable> Except(this where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (others is null || others.Length == 0) { @@ -1486,7 +1276,7 @@ public static IObservable> Except(this /// The type of the key. /// The sources. /// An observable which emits change sets. - /// + /// /// source /// or /// others. @@ -1495,10 +1285,7 @@ public static IObservable> Except(this where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Except); } @@ -1515,10 +1302,7 @@ public static IObservable> Except(this where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Except); } @@ -1535,10 +1319,7 @@ public static IObservable> Except(this where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Except); } @@ -1555,10 +1336,7 @@ public static IObservable> Except(this where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Except); } @@ -1572,7 +1350,7 @@ public static IObservable> Except(this /// The source. /// The time selector. /// An observable which emits change sets. - /// + /// /// source /// or /// timeSelector. @@ -1591,7 +1369,7 @@ public static IObservable> ExpireAfter( /// The time selector. /// The scheduler. /// An observable which emits change sets. - /// + /// /// source /// or /// timeSelector. @@ -1600,15 +1378,8 @@ public static IObservable> ExpireAfter( where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (timeSelector is null) - { - throw new ArgumentNullException(nameof(timeSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + timeSelector.ThrowArgumentNullExceptionIfNull(nameof(timeSelector)); return source.ExpireAfter(timeSelector, null, scheduler); } @@ -1625,7 +1396,7 @@ public static IObservable> ExpireAfter( /// This will result in a loss of accuracy of the time which the item is expired but is less computationally expensive. /// /// An observable of enumerable of the key values which has been removed. - /// source + /// source /// or /// timeSelector. public static IObservable> ExpireAfter(this IObservable> source, Func timeSelector, TimeSpan? pollingInterval) @@ -1645,22 +1416,15 @@ public static IObservable> ExpireAfter( /// /// The scheduler. /// An observable of enumerable of the key values which has been removed. - /// source + /// source /// or /// timeSelector. public static IObservable> ExpireAfter(this IObservable> source, Func timeSelector, TimeSpan? pollingInterval, IScheduler scheduler) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (timeSelector is null) - { - throw new ArgumentNullException(nameof(timeSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + timeSelector.ThrowArgumentNullExceptionIfNull(nameof(timeSelector)); return new TimeExpirer(source, timeSelector, pollingInterval, scheduler).ExpireAfter(); } @@ -1675,7 +1439,7 @@ public static IObservable> ExpireAfter( /// The time selector. Return null if the item should never be removed. /// The scheduler to perform the work on. /// An observable of enumerable of the key values which has been removed. - /// source + /// source /// or /// timeSelector. public static IObservable>> ExpireAfter(this ISourceCache source, Func timeSelector, IScheduler? scheduler = null) @@ -1694,7 +1458,7 @@ public static IObservable>> ExpireAfter< /// it may be worth setting the interval . /// /// An observable of enumerable of the key values which has been removed. - /// source + /// source /// or /// timeSelector. public static IObservable>> ExpireAfter(this ISourceCache source, Func timeSelector, TimeSpan? interval = null) @@ -1712,10 +1476,7 @@ public static IObservable> EnsureUniqueKeys(source).Run(); } @@ -1733,30 +1494,20 @@ public static IObservable> EnsureUniqueKeys /// The scheduler. /// An observable of enumerable of the key values which has been removed. - /// source + /// source /// or /// timeSelector. - [SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Deliberate capture.")] public static IObservable>> ExpireAfter(this ISourceCache source, Func timeSelector, TimeSpan? pollingInterval, IScheduler? scheduler) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (timeSelector is null) - { - throw new ArgumentNullException(nameof(timeSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + timeSelector.ThrowArgumentNullExceptionIfNull(nameof(timeSelector)); scheduler ??= Scheduler.Default; return Observable.Create>>( - observer => - { - return source.Connect().ForExpiry(timeSelector, pollingInterval, scheduler).Finally(observer.OnCompleted).Subscribe( + observer => source.Connect().ForExpiry(timeSelector, pollingInterval, scheduler).Finally(observer.OnCompleted).Subscribe( toRemove => { try @@ -1775,8 +1526,7 @@ public static IObservable>> ExpireAfter< { observer.OnError(ex); } - }); - }); + })); } /// @@ -1792,7 +1542,7 @@ public static IObservable> Filter(this where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new StaticFilter(source, filter, suppressEmptyChangeSets).Run(); } @@ -1810,8 +1560,8 @@ public static IObservable> Filter(this where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (predicateChanged is null) throw new ArgumentNullException(nameof(predicateChanged)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + predicateChanged.ThrowArgumentNullExceptionIfNull(nameof(predicateChanged)); return source.Filter(predicateChanged, Observable.Empty(), suppressEmptyChangeSets); } @@ -1829,8 +1579,8 @@ public static IObservable> Filter(this where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (reapplyFilter is null) throw new ArgumentNullException(nameof(reapplyFilter)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + reapplyFilter.ThrowArgumentNullExceptionIfNull(nameof(reapplyFilter)); return source.Filter(Observable.Empty>(), reapplyFilter, suppressEmptyChangeSets); } @@ -1849,9 +1599,9 @@ public static IObservable> Filter(this where TObject : notnull where TKey : notnull { - if (source is null) throw new ArgumentNullException(nameof(source)); - if (predicateChanged is null) throw new ArgumentNullException(nameof(predicateChanged)); - if (reapplyFilter is null) throw new ArgumentNullException(nameof(reapplyFilter)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + predicateChanged.ThrowArgumentNullExceptionIfNull(nameof(predicateChanged)); + reapplyFilter.ThrowArgumentNullExceptionIfNull(nameof(reapplyFilter)); return new DynamicFilter(source, predicateChanged, reapplyFilter, suppressEmptyChangeSets).Run(); } @@ -1871,8 +1621,8 @@ public static IObservable> FilterOnObservable(source, filterFactory, buffer, scheduler).Run(); } @@ -1892,7 +1642,8 @@ public static IObservable> FilterOnObservable filterFactory(obj), buffer, scheduler); } @@ -1916,20 +1667,9 @@ public static IObservable> FilterOnProperty(source, propertySelector, predicate, propertyChangedThrottle, scheduler).Run(); } @@ -1941,19 +1681,12 @@ public static IObservable> FilterOnPropertyThe source. /// The finally action. /// An observable which has always a finally action applied. - /// source. + /// source. [Obsolete("This can cause unhandled exception issues so do not use")] public static IObservable FinallySafe(this IObservable source, Action finallyAction) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (finallyAction is null) - { - throw new ArgumentNullException(nameof(finallyAction)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + finallyAction.ThrowArgumentNullExceptionIfNull(nameof(finallyAction)); return new FinallySafe(source, finallyAction).Run(); } @@ -1965,15 +1698,12 @@ public static IObservable FinallySafe(this IObservable source, Action f /// The type of the key. /// The source. /// An observable which emits change set values on a flatten result. - /// source. + /// source. public static IObservable> Flatten(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.SelectMany(changes => changes); } @@ -1989,10 +1719,7 @@ public static IObservable> FlattenBufferResult x.Count != 0).Select(updates => new ChangeSet(updates.SelectMany(u => u))); } @@ -2009,15 +1736,8 @@ public static IObservable> ForEachChange changes.ForEach(action)); } @@ -2043,25 +1763,10 @@ public static IObservable> FullJoin resultSelector(leftValue, rightValue)); } @@ -2087,25 +1792,10 @@ public static IObservable> FullJoin(left, right, rightKeySelector, resultSelector).Run(); } @@ -2131,25 +1821,10 @@ public static IObservable> FullJoinMany resultSelector(leftValue, rightValue)); } @@ -2175,25 +1850,10 @@ public static IObservable> FullJoinMany(left, right, rightKeySelector, resultSelector).Run(); } @@ -2219,20 +1879,9 @@ public static IObservable> Group(source, groupSelector, resultGroupSource).Run(); } @@ -2251,15 +1900,8 @@ public static IObservable> Group(source, groupSelectorKey, null).Run(); } @@ -2274,7 +1916,7 @@ public static IObservable> GroupThe group selector key. /// Invoke to the for the grouping to be re-evaluated. /// An observable which will emit group change sets. - /// + /// /// source /// or /// groupSelectorKey @@ -2286,20 +1928,9 @@ public static IObservable> Group(source, groupSelectorKey, regrouper).Run(); } @@ -2321,15 +1952,8 @@ public static IObservable> GroupOnProp where TKey : notnull where TGroupKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertySelector is null) - { - throw new ArgumentNullException(nameof(propertySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertySelector.ThrowArgumentNullExceptionIfNull(nameof(propertySelector)); return new GroupOnProperty(source, propertySelector, propertyChangedThrottle, scheduler).Run(); } @@ -2351,15 +1975,8 @@ public static IObservable> Gr where TKey : notnull where TGroupKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertySelector is null) - { - throw new ArgumentNullException(nameof(propertySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertySelector.ThrowArgumentNullExceptionIfNull(nameof(propertySelector)); return new GroupOnPropertyWithImmutableState(source, propertySelector, propertyChangedThrottle, scheduler).Run(); } @@ -2374,7 +1991,7 @@ public static IObservable> Gr /// The group selector key. /// Invoke to the for the grouping to be re-evaluated. /// An observable which will emit immutable group change sets. - /// + /// /// source /// or /// groupSelectorKey @@ -2386,15 +2003,8 @@ public static IObservable> Gr where TKey : notnull where TGroupKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (groupSelectorKey is null) - { - throw new ArgumentNullException(nameof(groupSelectorKey)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + groupSelectorKey.ThrowArgumentNullExceptionIfNull(nameof(groupSelectorKey)); return new GroupOnImmutable(source, groupSelectorKey, regrouper).Run(); } @@ -2450,15 +2060,8 @@ public static IObservable> IncludeUpdateWhen @@ -2489,25 +2092,10 @@ public static IObservable> IncludeUpdateWhen resultSelector(leftValue, rightValue)); } @@ -2533,25 +2121,10 @@ public static IObservable> IncludeUpdateWhen(left, right, rightKeySelector, resultSelector).Run(); } @@ -2577,25 +2150,10 @@ public static IObservable> InnerJoinMany resultSelector(leftValue, rightValue)); } @@ -2621,25 +2179,10 @@ public static IObservable> InnerJoinMany(left, right, rightKeySelector, resultSelector).Run(); } @@ -2675,25 +2218,10 @@ public static IObservable> LeftJoin resultSelector(leftValue, rightValue)); } @@ -2718,25 +2246,10 @@ public static IObservable> LeftJoin(left, right, rightKeySelector, resultSelector).Run(); } @@ -2762,25 +2275,10 @@ public static IObservable> LeftJoinMany resultSelector(leftValue, rightValue)); } @@ -2806,25 +2304,10 @@ public static IObservable> LeftJoinMany(left, right, rightKeySelector, resultSelector).Run(); } @@ -2838,16 +2321,13 @@ public static IObservable> LeftJoinManyThe source. /// The size. /// An observable which emits change sets. - /// source. - /// size cannot be zero. + /// source. + /// size cannot be zero. public static IObservable> LimitSizeTo(this IObservable> source, int size) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (size <= 0) { @@ -2867,16 +2347,13 @@ public static IObservable> LimitSizeTo( /// The size limit. /// The scheduler. /// An observable which emits the key value pairs. - /// source. - /// Size limit must be greater than zero. + /// source. + /// Size limit must be greater than zero. public static IObservable>> LimitSizeTo(this ISourceCache source, int sizeLimit, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (sizeLimit <= 0) { @@ -2915,22 +2392,15 @@ public static IObservable>> LimitSizeTo< /// The source. /// The observable selector. /// An observable which emits the transformed value. - /// source + /// source /// or /// observableSelector. public static IObservable MergeMany(this IObservable> source, Func> observableSelector) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeMany(source, observableSelector).Run(); } @@ -2945,22 +2415,15 @@ public static IObservable MergeMany(t /// The source. /// The observable selector. /// An observable which emits the transformed value. - /// source + /// source /// or /// observableSelector. public static IObservable MergeMany(this IObservable> source, Func> observableSelector) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeMany(source, observableSelector).Run(); } @@ -2977,7 +2440,7 @@ public static IObservable> MergeChangeSets(source, equalityComparer: null, comparer: null).Run(); } @@ -2995,8 +2458,8 @@ public static IObservable> MergeChangeSets(source, equalityComparer: null, comparer).Run(); } @@ -3014,8 +2477,8 @@ public static IObservable> MergeChangeSets(source, equalityComparer, comparer: null).Run(); } @@ -3034,9 +2497,9 @@ public static IObservable> MergeChangeSets(source, equalityComparer, comparer).Run(); } @@ -3056,8 +2519,8 @@ public static IObservable> MergeChangeSets> MergeChangeSets> MergeChangeSets> MergeChangeSets> MergeChangeSets> MergeChangeSets> MergeChangeSets> MergeChangeSets> MergeChangeSets(source, equalityComparer: null, comparer: null, completable, scheduler).Run(); } @@ -3259,8 +2722,8 @@ public static IObservable> MergeChangeSets(source, equalityComparer: null, comparer, completable, scheduler).Run(); } @@ -3280,8 +2743,8 @@ public static IObservable> MergeChangeSets(source, equalityComparer, comparer: null, completable, scheduler).Run(); } @@ -3302,9 +2765,9 @@ public static IObservable> MergeChangeSets(source, equalityComparer, comparer, completable, scheduler).Run(); } @@ -3327,7 +2790,7 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return source.MergeManyChangeSets((t, _) => observableSelector(t), comparer); } @@ -3350,9 +2813,9 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); - if (comparer == null) throw new ArgumentNullException(nameof(comparer)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); return source.MergeManyChangeSets(observableSelector, equalityComparer: null, comparer: comparer); } @@ -3376,7 +2839,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return source.MergeManyChangeSets((t, _) => observableSelector(t), equalityComparer, comparer); } @@ -3400,8 +2864,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeManyCacheChangeSets(source, observableSelector, equalityComparer, comparer).Run(); } @@ -3426,7 +2890,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return source.MergeManyChangeSets((t, _) => observableSelector(t), sourceComparer, DefaultResortOnSourceRefresh, equalityComparer: null, childComparer); } @@ -3472,7 +2937,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return source.MergeManyChangeSets((t, _) => observableSelector(t), sourceComparer, resortOnSourceRefresh, equalityComparer: null, childComparer); } @@ -3519,7 +2985,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return source.MergeManyChangeSets((t, _) => observableSelector(t), sourceComparer, DefaultResortOnSourceRefresh, equalityComparer, childComparer); } @@ -3567,7 +3034,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return source.MergeManyChangeSets((t, _) => observableSelector(t), sourceComparer, resortOnSourceRefresh, equalityComparer, childComparer); } @@ -3594,9 +3062,9 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); - if (sourceComparer == null) throw new ArgumentNullException(nameof(sourceComparer)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); + sourceComparer.ThrowArgumentNullExceptionIfNull(nameof(sourceComparer)); return new MergeManyCacheChangeSetsSourceCompare(source, observableSelector, sourceComparer, equalityComparer, childComparer, resortOnSourceRefresh).Run(); } @@ -3611,22 +3079,15 @@ public static IObservable> MergeManyCh /// The source. /// The observable selector. /// An observable which emits the item with the value. - /// source + /// source /// or /// observableSelector. public static IObservable> MergeManyItems(this IObservable> source, Func> observableSelector) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeManyItems(source, observableSelector).Run(); } @@ -3641,22 +3102,15 @@ public static IObservable> MergeManyItemsThe source. /// The observable selector. /// An observable which emits the item with the value. - /// source + /// source /// or /// observableSelector. public static IObservable> MergeManyItems(this IObservable> source, Func> observableSelector) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeManyItems(source, observableSelector).Run(); } @@ -3667,7 +3121,7 @@ public static IObservable> MergeManyItemsThe type of the source observable. /// The source. /// An observable which monitors the status of the observable. - /// source. + /// source. public static IObservable MonitorStatus(this IObservable source) => new StatusMonitor(source).Run(); /// @@ -3677,15 +3131,12 @@ public static IObservable> MergeManyItemsThe type of the key. /// The source. /// An observable which emits change set values when not empty. - /// source. + /// source. public static IObservable> NotEmpty(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Where(changes => changes.Count != 0); } @@ -3702,15 +3153,8 @@ public static IObservable> OnItemAdded( where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (addAction is null) - { - throw new ArgumentNullException(nameof(addAction)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + addAction.ThrowArgumentNullExceptionIfNull(nameof(addAction)); return source.Do(changes => changes.Where(c => c.Reason == ChangeReason.Add).ForEach(c => addAction(c.Current))); } @@ -3727,22 +3171,18 @@ public static IObservable> OnItemRefreshed refreshAction2 = refreshAction; - if (source == null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (refreshAction2 == null) - { - throw new ArgumentNullException(nameof(refreshAction)); - } + var refreshAction2 = refreshAction; + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + refreshAction2.ThrowArgumentNullExceptionIfNull(nameof(refreshAction)); return source.Do(changes => { foreach (var change in changes.ToConcreteType()) { - if (change.Reason != ChangeReason.Refresh) continue; + if (change.Reason != ChangeReason.Refresh) + { + continue; + } refreshAction2(change.Current); } @@ -3758,7 +3198,7 @@ public static IObservable> OnItemRefreshedThe remove action. /// Should the remove action be invoked when the subscription is disposed. /// An observable which emits a change set with items being removed. - /// + /// /// source /// or /// removeAction. @@ -3767,8 +3207,8 @@ public static IObservable> OnItemRemoved(source, removeAction, invokeOnUnsubscribe).Run(); } @@ -3785,15 +3225,8 @@ public static IObservable> OnItemUpdated changes.Where(c => c.Reason == ChangeReason.Update).ForEach(c => updateAction(c.Current, c.Previous.Value))); } @@ -3806,7 +3239,7 @@ public static IObservable> OnItemUpdatedThe source. /// The others. /// An observable which emits change sets. - /// + /// /// source /// or /// others. @@ -3815,10 +3248,7 @@ public static IObservable> Or(this IObs where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (others is null || others.Length == 0) { @@ -3835,7 +3265,7 @@ public static IObservable> Or(this IObs /// The type of the key. /// The source. /// An observable which emits change sets. - /// + /// /// source /// or /// others. @@ -3844,10 +3274,7 @@ public static IObservable> Or(this ICol where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Or); } @@ -3864,10 +3291,7 @@ public static IObservable> Or(this IObs where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Or); } @@ -3884,10 +3308,7 @@ public static IObservable> Or(this IObs where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Or); } @@ -3904,10 +3325,7 @@ public static IObservable> Or(this IObs where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Or); } @@ -3924,15 +3342,8 @@ public static IObservable> Page(th where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (pageRequests is null) - { - throw new ArgumentNullException(nameof(pageRequests)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + pageRequests.ThrowArgumentNullExceptionIfNull(nameof(pageRequests)); return new Page(source, pageRequests).Run(); } @@ -3945,7 +3356,7 @@ public static IObservable> Page(th /// The source. /// The observable. /// A disposable which will unsubscribe from the source. - /// + /// /// source /// or /// keySelector. @@ -3954,10 +3365,7 @@ public static IDisposable PopulateFrom(this ISourceCache(this ISourceCacheThe source. /// The observable. /// A disposable which will unsubscribe from the source. - /// + /// /// source /// or /// keySelector. @@ -3979,10 +3387,7 @@ public static IDisposable PopulateFrom(this ISourceCache(this ISourceCacheThe source. /// The destination. /// A disposable which will unsubscribe from the source. - /// + /// /// source /// or /// destination. @@ -4004,15 +3409,8 @@ public static IDisposable PopulateInto(this IObservable destination.Edit(updater => updater.Clone(changes))); } @@ -4025,22 +3423,15 @@ public static IDisposable PopulateInto(this IObservableThe source. /// The destination. /// A disposable which will unsubscribe from the source. - /// source + /// source /// or /// destination. public static IDisposable PopulateInto(this IObservable> source, IIntermediateCache destination) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (destination is null) - { - throw new ArgumentNullException(nameof(destination)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); return source.Subscribe(changes => destination.Edit(updater => updater.Clone(changes))); } @@ -4057,15 +3448,8 @@ public static IDisposable PopulateInto(this IObservable destination.Edit(updater => updater.Clone(changes))); } @@ -4079,7 +3463,7 @@ public static IDisposable PopulateInto(this IObservableThe source. /// The result selector. /// An observable which emits the destination values. - /// + /// /// source /// or /// resultSelector. @@ -4088,15 +3472,8 @@ public static IObservable QueryWhenChanged QueryWhenChangedThe type of the key. /// The source. /// An observable which emits the query. - /// source. + /// source. public static IObservable> QueryWhenChanged(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new QueryWhenChanged(source).Run(); } @@ -4130,20 +3504,13 @@ public static IObservable> QueryWhenChanged /// The source. /// Should the query be triggered for observables on individual items. /// An observable that emits the query. - /// source. + /// source. public static IObservable> QueryWhenChanged(this IObservable> source, Func> itemChangedTrigger) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (itemChangedTrigger is null) - { - throw new ArgumentNullException(nameof(itemChangedTrigger)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + itemChangedTrigger.ThrowArgumentNullExceptionIfNull(nameof(itemChangedTrigger)); return new QueryWhenChanged(source, itemChangedTrigger).Run(); } @@ -4159,10 +3526,7 @@ public static IObservable> RefCount(thi where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new RefCount(source).Run(); } @@ -4174,15 +3538,12 @@ public static IObservable> RefCount(thi /// The type of the key. /// The source. /// The item. - /// source. + /// source. public static void Refresh(this ISourceCache source, TObject item) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Refresh(item)); } @@ -4194,15 +3555,12 @@ public static void Refresh(this ISourceCache sourc /// The type of the key. /// The source. /// The items. - /// source. + /// source. public static void Refresh(this ISourceCache source, IEnumerable items) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Refresh(items)); } @@ -4213,15 +3571,12 @@ public static void Refresh(this ISourceCache sourc /// The type of the object. /// The type of the key. /// The source. - /// source. + /// source. public static void Refresh(this ISourceCache source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Refresh()); } @@ -4234,15 +3589,12 @@ public static void Refresh(this ISourceCache sourc /// The type of the key. /// The source. /// The item. - /// source. + /// source. public static void Remove(this ISourceCache source, TObject item) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Remove(item)); } @@ -4255,15 +3607,12 @@ public static void Remove(this ISourceCache source /// The type of the key. /// The source. /// The key. - /// source. + /// source. public static void Remove(this ISourceCache source, TKey key) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Remove(key)); } @@ -4276,15 +3625,12 @@ public static void Remove(this ISourceCache source /// The type of the key. /// The source. /// The items. - /// source. + /// source. public static void Remove(this ISourceCache source, IEnumerable items) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Remove(items)); } @@ -4297,15 +3643,12 @@ public static void Remove(this ISourceCache source /// The type of the key. /// The source. /// The keys. - /// source. + /// source. public static void Remove(this ISourceCache source, IEnumerable keys) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Remove(keys)); } @@ -4318,15 +3661,12 @@ public static void Remove(this ISourceCache source /// The type of the key. /// The source. /// The key. - /// source. + /// source. public static void Remove(this IIntermediateCache source, TKey key) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Remove(key)); } @@ -4339,15 +3679,12 @@ public static void Remove(this IIntermediateCache /// The type of the key. /// The source. /// The keys. - /// source. + /// source. public static void Remove(this IIntermediateCache source, IEnumerable keys) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.Remove(keys)); } @@ -4366,10 +3703,7 @@ public static IObservable> RemoveKey(this IOb where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select( changes => @@ -4387,15 +3721,12 @@ public static IObservable> RemoveKey(this IOb /// The type of the key. /// The source. /// The key. - /// source. + /// source. public static void RemoveKey(this ISourceCache source, TKey key) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.RemoveKey(key)); } @@ -4408,15 +3739,12 @@ public static void RemoveKey(this ISourceCache sou /// The type of the key. /// The source. /// The keys. - /// source. + /// source. public static void RemoveKeys(this ISourceCache source, IEnumerable keys) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(updater => updater.RemoveKeys(keys)); } @@ -4441,25 +3769,10 @@ public static IObservable> RightJoin resultSelector(leftValue, rightValue)); } @@ -4484,25 +3797,10 @@ public static IObservable> RightJoin(left, right, rightKeySelector, resultSelector).Run(); } @@ -4528,25 +3826,10 @@ public static IObservable> RightJoinMany resultSelector(leftValue, rightValue)); } @@ -4572,25 +3855,10 @@ public static IObservable> RightJoinMany(left, right, rightKeySelector, resultSelector).Run(); } @@ -4602,15 +3870,12 @@ public static IObservable> RightJoinManyThe type of the key. /// The source. /// An observable which emits change sets. - /// source. + /// source. public static IObservable> SkipInitial(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.DeferUntilLoaded().Skip(1); } @@ -4627,7 +3892,7 @@ public static IObservable> SkipInitial( /// Sort optimisation flags. Specify one or more sort optimisations. /// The number of updates before the entire list is resorted (rather than inline sort). /// An observable which emits change sets. - /// + /// /// source /// or /// comparer. @@ -4636,15 +3901,8 @@ public static IObservable> Sort(t where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (comparer is null) - { - throw new ArgumentNullException(nameof(comparer)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); return new Sort(source, comparer, sortOptimisations, resetThreshold: resetThreshold).Run(); } @@ -4663,15 +3921,8 @@ public static IObservable> Sort(t where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (comparerObservable is null) - { - throw new ArgumentNullException(nameof(comparerObservable)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + comparerObservable.ThrowArgumentNullExceptionIfNull(nameof(comparerObservable)); return new Sort(source, null, sortOptimisations, comparerObservable, resetThreshold: resetThreshold).Run(); } @@ -4691,15 +3942,8 @@ public static IObservable> Sort(t where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (comparerObservable is null) - { - throw new ArgumentNullException(nameof(comparerObservable)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + comparerObservable.ThrowArgumentNullExceptionIfNull(nameof(comparerObservable)); return new Sort(source, null, sortOptimisations, comparerObservable, resorter, resetThreshold).Run(); } @@ -4719,15 +3963,8 @@ public static IObservable> Sort(t where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (resorter is null) - { - throw new ArgumentNullException(nameof(resorter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + resorter.ThrowArgumentNullExceptionIfNull(nameof(resorter)); return new Sort(source, comparer, sortOptimisations, null, resorter, resetThreshold).Run(); } @@ -4855,10 +4092,7 @@ public static IObservable> StartWithItem where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.StartWithItem(item, item.Key); } @@ -4876,10 +4110,7 @@ public static IObservable> StartWithItem(ChangeReason.Add, key, item); return source.StartWith(new ChangeSet { change }); @@ -4893,7 +4124,7 @@ public static IObservable> StartWithItemThe source. /// The subscription function. /// An observable which emits a change set. - /// source + /// source /// or /// subscriptionFactory. /// @@ -4903,15 +4134,8 @@ public static IObservable> SubscribeMany(source, subscriptionFactory).Run(); } @@ -4924,7 +4148,7 @@ public static IObservable> SubscribeManyThe source. /// The subscription function. /// An observable which emits a change set. - /// source + /// source /// or /// subscriptionFactory. /// @@ -4934,15 +4158,8 @@ public static IObservable> SubscribeMany(source, subscriptionFactory).Run(); } @@ -4974,10 +4191,7 @@ public static IObservable> Switch(this where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Select(cache => cache.Connect()).Switch(); } @@ -4998,10 +4212,7 @@ public static IObservable> Switch(this where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return new Switch(sources).Run(); } @@ -5029,22 +4240,15 @@ public static IObservable> ToCollectionRemove the oldest items when the size has reached this limit. /// The scheduler (only used for time expiry). /// An observable which will emit changes. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable source, Func keySelector, Func? expireAfter = null, int limitSizeTo = -1, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return new ToObservableChangeSet(source, keySelector, expireAfter, limitSizeTo, scheduler).Run(); } @@ -5061,22 +4265,15 @@ public static IObservable> ToObservableChangeSetRemove the oldest items when the size has reached this limit. /// The scheduler (only used for time expiry). /// An observable change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable> source, Func keySelector, Func? expireAfter = null, int limitSizeTo = -1, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return new ToObservableChangeSet(source, keySelector, expireAfter, limitSizeTo, scheduler).Run(); } @@ -5090,15 +4287,12 @@ public static IObservable> ToObservableChangeSetThe key value. /// Optional instance used to determine if an object value has changed. /// An observable optional. - /// source is null. + /// source is null. public static IObservable> ToObservableOptional(this IObservable> source, TKey key, IEqualityComparer? equalityComparer = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new ToObservableOptional(source, key, equalityComparer).Run(); } @@ -5113,7 +4307,7 @@ public static IObservable> ToObservableOptional /// Indicates if an initial Optional None should be emitted if the value doesn't exist. /// Optional instance used to determine if an object value has changed. /// An observable optional. - /// source is null. + /// source is null. public static IObservable> ToObservableOptional(this IObservable> source, TKey key, bool initialOptionalWhenMissing, IEqualityComparer? equalityComparer = null) where TObject : notnull where TKey : notnull @@ -5140,16 +4334,13 @@ public static IObservable> ToObservableOptional /// The source. /// The size. /// An observable which will emit virtual change sets. - /// source. - /// size;Size should be greater than zero. + /// source. + /// size;Size should be greater than zero. public static IObservable> Top(this IObservable> source, int size) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (size <= 0) { @@ -5168,21 +4359,14 @@ public static IObservable> Top(t /// The comparer. /// The size. /// An observable which will emit virtual change sets. - /// source. - /// size;Size should be greater than zero. + /// source. + /// size;Size should be greater than zero. public static IObservable> Top(this IObservable> source, IComparer comparer, int size) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (comparer is null) - { - throw new ArgumentNullException(nameof(comparer)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); if (size <= 0) { @@ -5237,7 +4421,7 @@ public static IObservable> ToSortedCollection /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, bool transformOnRefresh) @@ -5245,15 +4429,8 @@ public static IObservable> Transform transformFactory(current), transformOnRefresh); } @@ -5270,7 +4447,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, bool transformOnRefresh) @@ -5278,15 +4455,8 @@ public static IObservable> Transform transformFactory(current, key), transformOnRefresh); } @@ -5303,7 +4473,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func, TKey, TDestination> transformFactory, bool transformOnRefresh) @@ -5311,15 +4481,8 @@ public static IObservable> Transform(source, transformFactory, transformOnRefresh: transformOnRefresh).Run(); } @@ -5336,7 +4499,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, IObservable>? forceTransform = null) @@ -5344,15 +4507,8 @@ public static IObservable> Transform transformFactory(current), forceTransform?.ForForced()); } @@ -5369,7 +4525,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, IObservable>? forceTransform = null) @@ -5377,15 +4533,8 @@ public static IObservable> Transform transformFactory(current, key), forceTransform); } @@ -5402,7 +4551,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func, TKey, TDestination> transformFactory, IObservable>? forceTransform = null) @@ -5410,16 +4559,8 @@ public static IObservable> Transform(source, transformFactory, forceTransform).Run(); @@ -5440,7 +4581,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, IObservable forceTransform) @@ -5460,7 +4601,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, IObservable forceTransform) @@ -5468,20 +4609,9 @@ public static IObservable> Transform transformFactory(cur, key), forceTransform.ForForced()); } @@ -5498,7 +4628,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func, TKey, TDestination> transformFactory, IObservable forceTransform) @@ -5506,20 +4636,9 @@ public static IObservable> Transform()); } @@ -5536,23 +4655,17 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. + [SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync(this IObservable> source, Func> transformFactory, IObservable>? forceTransform = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return source.TransformAsync((current, _, _) => transformFactory(current), forceTransform); } @@ -5569,23 +4682,17 @@ public static IObservable> TransformAsync /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. + [SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync(this IObservable> source, Func> transformFactory, IObservable>? forceTransform = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return source.TransformAsync((current, _, key) => transformFactory(current, key), forceTransform); } @@ -5602,23 +4709,17 @@ public static IObservable> TransformAsync /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. + [SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync(this IObservable> source, Func, TKey, Task> transformFactory, IObservable>? forceTransform = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return new TransformAsync(source, transformFactory, null, forceTransform).Run(); } @@ -5705,7 +4806,7 @@ public static IObservable> TransformMa /// /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable>? forceTransform = null) @@ -5713,20 +4814,9 @@ public static IObservable> TransformSafe transformFactory(current), errorHandler, forceTransform.ForForced()); } @@ -5745,7 +4835,7 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable>? forceTransform = null) @@ -5753,20 +4843,9 @@ public static IObservable> TransformSafe transformFactory(current, key), errorHandler, forceTransform); } @@ -5785,7 +4864,7 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func, TKey, TDestination> transformFactory, Action> errorHandler, IObservable>? forceTransform = null) @@ -5793,21 +4872,9 @@ public static IObservable> TransformSafe(source, transformFactory, forceTransform, errorHandler).Run(); @@ -5830,7 +4897,7 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable forceTransform) @@ -5852,7 +4919,7 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func transformFactory, Action> errorHandler, IObservable forceTransform) @@ -5860,20 +4927,9 @@ public static IObservable> TransformSafe transformFactory(cur, key), errorHandler, forceTransform.ForForced()); } @@ -5892,7 +4948,7 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func, TKey, TDestination> transformFactory, Action> errorHandler, IObservable forceTransform) @@ -5900,20 +4956,9 @@ public static IObservable> TransformSafe()); } @@ -5931,28 +4976,18 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. + [SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformSafeAsync(this IObservable> source, Func> transformFactory, Action> errorHandler, IObservable>? forceTransform = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } - - if (errorHandler is null) - { - throw new ArgumentNullException(nameof(errorHandler)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); + errorHandler.ThrowArgumentNullExceptionIfNull(nameof(errorHandler)); return source.TransformSafeAsync((current, _, _) => transformFactory(current), errorHandler, forceTransform); } @@ -5970,28 +5005,18 @@ public static IObservable> TransformSafeAsync /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. + [SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformSafeAsync(this IObservable> source, Func> transformFactory, Action> errorHandler, IObservable>? forceTransform = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } - - if (errorHandler is null) - { - throw new ArgumentNullException(nameof(errorHandler)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); + errorHandler.ThrowArgumentNullExceptionIfNull(nameof(errorHandler)); return source.TransformSafeAsync((current, _, key) => transformFactory(current, key), errorHandler, forceTransform); } @@ -6009,28 +5034,18 @@ public static IObservable> TransformSafeAsync /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. + [SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformSafeAsync(this IObservable> source, Func, TKey, Task> transformFactory, Action> errorHandler, IObservable>? forceTransform = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } - - if (errorHandler is null) - { - throw new ArgumentNullException(nameof(errorHandler)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); + errorHandler.ThrowArgumentNullExceptionIfNull(nameof(errorHandler)); return new TransformAsync(source, transformFactory, errorHandler, forceTransform).Run(); } @@ -6048,15 +5063,8 @@ public static IObservable, TKey>> TransformToTree where TObject : class where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (pivotOn is null) - { - throw new ArgumentNullException(nameof(pivotOn)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + pivotOn.ThrowArgumentNullExceptionIfNull(nameof(pivotOn)); return new TreeBuilder(source, pivotOn, predicateChanged).Run(); } @@ -6073,7 +5081,7 @@ public static IObservable, TKey>> TransformToTree /// /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformWithInlineUpdate(this IObservable> source, Func transformFactory, Action updateAction) @@ -6081,20 +5089,9 @@ public static IObservable> TransformWithInlineUpd where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } - - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); return new TransformWithInlineUpdate(source, transformFactory, updateAction).Run(); } @@ -6112,7 +5109,7 @@ public static IObservable> TransformWithInlineUpd /// /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformWithInlineUpdate(this IObservable> source, Func transformFactory, Action updateAction, Action> errorHandler) @@ -6120,25 +5117,10 @@ public static IObservable> TransformWithInlineUpd where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } - - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } - - if (errorHandler is null) - { - throw new ArgumentNullException(nameof(errorHandler)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); + errorHandler.ThrowArgumentNullExceptionIfNull(nameof(errorHandler)); return new TransformWithInlineUpdate(source, transformFactory, updateAction, errorHandler).Run(); } @@ -6154,12 +5136,9 @@ public static IObservable> TreatMovesAsRemoveAdd where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - IEnumerable> ReplaceMoves(IChangeSet items) + static IEnumerable> ReplaceMoves(IChangeSet items) { foreach (var change in items.ToConcreteType()) { @@ -6196,7 +5175,7 @@ IEnumerable> ReplaceMoves(IChangeSet items) /// Selector which returns the target observable. /// The equality condition. /// An observable which boolean values indicating if true. - /// source. + /// source. public static IObservable TrueForAll(this IObservable> source, Func> observableSelector, Func equalityCondition) where TObject : notnull where TKey : notnull @@ -6219,7 +5198,7 @@ public static IObservable TrueForAll(this IObservab /// Selector which returns the target observable. /// The equality condition. /// An observable which boolean values indicating if true. - /// source. + /// source. public static IObservable TrueForAll(this IObservable> source, Func> observableSelector, Func equalityCondition) where TObject : notnull where TKey : notnull @@ -6238,7 +5217,7 @@ public static IObservable TrueForAll(this IObservab /// The observable selector. /// The equality condition. /// An observable which boolean values indicating if true. - /// + /// /// source /// or /// observableSelector @@ -6263,7 +5242,7 @@ public static IObservable TrueForAny(this IObservab /// The observable selector. /// The equality condition. /// An observable which boolean values indicating if true. - /// + /// /// source /// or /// observableSelector @@ -6275,20 +5254,9 @@ public static IObservable TrueForAny(this IObservab where TKey : notnull where TValue : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } - - if (equalityCondition is null) - { - throw new ArgumentNullException(nameof(equalityCondition)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); + equalityCondition.ThrowArgumentNullExceptionIfNull(nameof(equalityCondition)); return source.TrueFor(observableSelector, items => items.Any(o => o.LatestValue.HasValue && equalityCondition(o.LatestValue.Value))); } @@ -6312,20 +5280,13 @@ public static IObservable> UpdateIndexThe source. /// The virirtualising requests. /// An observable which will emit virtual change sets. - /// source. + /// source. public static IObservable> Virtualise(this IObservable> source, IObservable virtualRequests) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (virtualRequests is null) - { - throw new ArgumentNullException(nameof(virtualRequests)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + virtualRequests.ThrowArgumentNullExceptionIfNull(nameof(virtualRequests)); return new Virtualise(source, virtualRequests).Run(); } @@ -6342,10 +5303,7 @@ public static IObservable> Watch(this IObse where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.SelectMany(updates => updates).Where(update => update.Key.Equals(key)); } @@ -6358,15 +5316,12 @@ public static IObservable> Watch(this IObse /// The source. /// The key. /// An observable which emits the object value. - /// source. + /// source. public static IObservable WatchValue(this IObservableCache source, TKey key) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Watch(key).Select(u => u.Current); } @@ -6379,15 +5334,12 @@ public static IObservable WatchValue(this IObservableCac /// The source. /// The key. /// An observable which emits the object value. - /// source. + /// source. public static IObservable WatchValue(this IObservable> source, TKey key) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Watch(key).Select(u => u.Current); } @@ -6404,10 +5356,7 @@ public static IObservable WatchValue(this IObservable t.WhenAnyPropertyChanged(propertiesToMonitor)); } @@ -6426,15 +5375,8 @@ public static IObservable> WhenPropertyChanged t.WhenPropertyChanged(propertyAccessor, notifyOnInitialValue)); } @@ -6453,15 +5395,8 @@ public static IObservable> WhenPropertyChanged t.WhenChanged(propertyAccessor, notifyOnInitialValue)); } @@ -6474,16 +5409,14 @@ public static IObservable> WhenPropertyChangedThe source. /// The reasons. /// An observable which emits a change set with items matching the reasons. - /// reasons. - /// Must select at least on reason. + /// reasons. + /// Must select at least on reason. public static IObservable> WhereReasonsAre(this IObservable> source, params ChangeReason[] reasons) where TObject : notnull where TKey : notnull { - if (reasons is null) - { - throw new ArgumentNullException(nameof(reasons)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + reasons.ThrowArgumentNullExceptionIfNull(nameof(reasons)); if (reasons.Length == 0) { @@ -6503,16 +5436,13 @@ public static IObservable> WhereReasonsAreThe source. /// The reasons. /// An observable which emits a change set with items not matching the reasons. - /// reasons. - /// Must select at least on reason. + /// reasons. + /// Must select at least on reason. public static IObservable> WhereReasonsAreNot(this IObservable> source, params ChangeReason[] reasons) where TObject : notnull where TKey : notnull { - if (reasons is null) - { - throw new ArgumentNullException(nameof(reasons)); - } + reasons.ThrowArgumentNullExceptionIfNull(nameof(reasons)); if (reasons.Length == 0) { @@ -6533,7 +5463,7 @@ public static IObservable> WhereReasonsAreNotThe source. /// The others. /// An observable which emits a change set. - /// + /// /// source /// or /// others. @@ -6542,10 +5472,7 @@ public static IObservable> Xor(this IOb where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (others is null || others.Length == 0) { @@ -6563,7 +5490,7 @@ public static IObservable> Xor(this IOb /// The type of the key. /// The source. /// An observable which emits a change set. - /// + /// /// source /// or /// others. @@ -6572,10 +5499,7 @@ public static IObservable> Xor(this ICo where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Xor); } @@ -6592,10 +5516,7 @@ public static IObservable> Xor(this IOb where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Xor); } @@ -6612,10 +5533,7 @@ public static IObservable> Xor(this IOb where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Xor); } @@ -6632,10 +5550,7 @@ public static IObservable> Xor(this IOb where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Combine(CombineOperator.Xor); } @@ -6653,7 +5568,7 @@ public static IObservable> Xor(this IOb /// /// The scheduler. /// An observable of enumerable of the key values which has been removed. - /// source + /// source /// or /// timeSelector. internal static IObservable>> ForExpiry(this IObservable> source, Func timeSelector, TimeSpan? interval, IScheduler scheduler) @@ -6664,10 +5579,7 @@ private static IObservable> Combine(thi where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return Observable.Create>( observer => @@ -6682,10 +5594,7 @@ private static IObservable> Combine(thi where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return Observable.Create>( observer => @@ -6700,10 +5609,7 @@ private static IObservable> Combine(thi where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new DynamicCombiner(source, type).Run(); } @@ -6712,10 +5618,7 @@ private static IObservable> Combine(thi where TObject : notnull where TKey : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return Observable.Create>( observer => @@ -6732,11 +5635,11 @@ void UpdateAction(IChangeSet updates) } } - IDisposable subscriber = Disposable.Empty; + var subscriber = Disposable.Empty; try { var combiner = new Combiner(type, UpdateAction); - subscriber = combiner.Subscribe(sources.ToArray()); + subscriber = combiner.Subscribe([.. sources]); } catch (Exception ex) { @@ -6752,10 +5655,7 @@ private static IObservable> Combine(thi where TObject : notnull where TKey : notnull { - if (combineTarget is null) - { - throw new ArgumentNullException(nameof(combineTarget)); - } + combineTarget.ThrowArgumentNullExceptionIfNull(nameof(combineTarget)); return Observable.Create>( observer => @@ -6773,14 +5673,14 @@ void UpdateAction(IChangeSet updates) } } - IDisposable subscriber = Disposable.Empty; + var subscriber = Disposable.Empty; try { var list = combineTarget.ToList(); list.Insert(0, source); var combiner = new Combiner(type, UpdateAction); - subscriber = combiner.Subscribe(list.ToArray()); + subscriber = combiner.Subscribe([.. list]); } catch (Exception ex) { @@ -6796,7 +5696,7 @@ void UpdateAction(IChangeSet updates) where TKey : notnull => source?.Select( _ => { - bool Transformer(TSource item, TKey key) => true; + static bool Transformer(TSource item, TKey key) => true; return (Func)Transformer; }); diff --git a/src/DynamicData/Cache/PageRequest.cs b/src/DynamicData/Cache/PageRequest.cs index 3f105410f..36f49463f 100644 --- a/src/DynamicData/Cache/PageRequest.cs +++ b/src/DynamicData/Cache/PageRequest.cs @@ -98,12 +98,12 @@ public bool Equals(IPageRequest? x, IPageRequest? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } diff --git a/src/DynamicData/Cache/PageResponse.cs b/src/DynamicData/Cache/PageResponse.cs index e438f508f..317163429 100644 --- a/src/DynamicData/Cache/PageResponse.cs +++ b/src/DynamicData/Cache/PageResponse.cs @@ -42,7 +42,7 @@ public override bool Equals(object? obj) return false; } - if (!(obj is IPageResponse pageResponse)) + if (obj is not IPageResponse pageResponse) { return false; } @@ -60,7 +60,7 @@ public override int GetHashCode() { unchecked { - int hashCode = Pages; + var hashCode = Pages; hashCode = (hashCode * 397) ^ Page; hashCode = (hashCode * 397) ^ TotalSize; hashCode = (hashCode * 397) ^ PageSize; @@ -85,12 +85,12 @@ public bool Equals(IPageResponse? x, IPageResponse? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } @@ -112,7 +112,7 @@ public int GetHashCode(IPageResponse? obj) unchecked { - int hashCode = obj.PageSize; + var hashCode = obj.PageSize; hashCode = (hashCode * 397) ^ obj.TotalSize; hashCode = (hashCode * 397) ^ obj.Page; hashCode = (hashCode * 397) ^ obj.Pages; diff --git a/src/DynamicData/Cache/PagedChangeSet.cs b/src/DynamicData/Cache/PagedChangeSet.cs index 35ad97031..587d99a05 100644 --- a/src/DynamicData/Cache/PagedChangeSet.cs +++ b/src/DynamicData/Cache/PagedChangeSet.cs @@ -12,7 +12,7 @@ internal sealed class PagedChangeSet : ChangeSet, where TObject : notnull where TKey : notnull { - public static readonly new IPagedChangeSet Empty = new PagedChangeSet(); + public static new readonly IPagedChangeSet Empty = new PagedChangeSet(); public PagedChangeSet(IKeyValueCollection sortedItems, IEnumerable> updates, IPageResponse response) : base(updates) diff --git a/src/DynamicData/Cache/SortedChangeSet.cs b/src/DynamicData/Cache/SortedChangeSet.cs index ffe203975..e39079e77 100644 --- a/src/DynamicData/Cache/SortedChangeSet.cs +++ b/src/DynamicData/Cache/SortedChangeSet.cs @@ -11,18 +11,12 @@ internal class SortedChangeSet : ChangeSet, ISorte where TObject : notnull where TKey : notnull { - public static readonly new ISortedChangeSet Empty = new SortedChangeSet(); + public static new readonly ISortedChangeSet Empty = new SortedChangeSet(); public SortedChangeSet(IKeyValueCollection sortedItems, IEnumerable> updates) - : base(updates) - { - SortedItems = sortedItems; - } - - private SortedChangeSet() - { - SortedItems = new KeyValueCollection(); - } + : base(updates) => SortedItems = sortedItems; + + private SortedChangeSet() => SortedItems = new KeyValueCollection(); public IKeyValueCollection SortedItems { get; } diff --git a/src/DynamicData/Cache/SourceCache.cs b/src/DynamicData/Cache/SourceCache.cs index 52a7edd43..caab49f94 100644 --- a/src/DynamicData/Cache/SourceCache.cs +++ b/src/DynamicData/Cache/SourceCache.cs @@ -18,7 +18,7 @@ namespace DynamicData; /// Initializes a new instance of the class. /// /// The key selector. -/// keySelector. +/// keySelector. [DebuggerDisplay("SourceCache<{typeof(TObject).Name}, {typeof(TKey).Name}> ({Count} Items)")] public sealed class SourceCache(Func keySelector) : ISourceCache where TObject : notnull diff --git a/src/DynamicData/Cache/SourceCacheEx.cs b/src/DynamicData/Cache/SourceCacheEx.cs index e3a63c3e7..5afb90d3f 100644 --- a/src/DynamicData/Cache/SourceCacheEx.cs +++ b/src/DynamicData/Cache/SourceCacheEx.cs @@ -23,13 +23,5 @@ public static class SourceCacheEx public static IObservable> Cast(this IObservableCache source, Func converter) where TSource : notnull where TKey : notnull - where TDestination : notnull - { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - return source.Connect().Cast(converter); - } + where TDestination : notnull => source is null ? throw new ArgumentNullException(nameof(source)) : source.Connect().Cast(converter); } diff --git a/src/DynamicData/Cache/Tests/TestEx.cs b/src/DynamicData/Cache/Tests/TestEx.cs index 351f8ae46..b3e73db1e 100644 --- a/src/DynamicData/Cache/Tests/TestEx.cs +++ b/src/DynamicData/Cache/Tests/TestEx.cs @@ -27,14 +27,11 @@ public static ChangeSetAggregator AsAggregator(thi /// The type of the value. /// The source. /// The distinct change set aggregator. - /// source. + /// source. public static DistinctChangeSetAggregator AsAggregator(this IObservable> source) where TValue : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new DistinctChangeSetAggregator(source); } @@ -46,15 +43,12 @@ public static DistinctChangeSetAggregator AsAggregator(this IObs /// The type of the key. /// The source. /// The sorted change set aggregator. - /// source. + /// source. public static SortedChangeSetAggregator AsAggregator(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new SortedChangeSetAggregator(source); } @@ -66,15 +60,12 @@ public static SortedChangeSetAggregator AsAggregatorThe type of the key. /// The source. /// The virtual change set aggregator. - /// source. + /// source. public static VirtualChangeSetAggregator AsAggregator(this IObservable> source) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new VirtualChangeSetAggregator(source); } @@ -90,10 +81,7 @@ public static PagedChangeSetAggregator AsAggregator(source); } diff --git a/src/DynamicData/Cache/VirtualChangeSet.cs b/src/DynamicData/Cache/VirtualChangeSet.cs index 2a7ef3b1e..5f599f5cd 100644 --- a/src/DynamicData/Cache/VirtualChangeSet.cs +++ b/src/DynamicData/Cache/VirtualChangeSet.cs @@ -11,7 +11,7 @@ internal sealed class VirtualChangeSet : ChangeSet where TObject : notnull where TKey : notnull { - public static readonly new IVirtualChangeSet Empty = new VirtualChangeSet(); + public static new readonly IVirtualChangeSet Empty = new VirtualChangeSet(); public VirtualChangeSet(IEnumerable> items, IKeyValueCollection sortedItems, IVirtualResponse response) : base(items) @@ -30,19 +30,13 @@ private VirtualChangeSet() public IKeyValueCollection SortedItems { get; } - public static bool operator ==(VirtualChangeSet left, VirtualChangeSet right) - { - return Equals(left, right); - } + public static bool operator ==(VirtualChangeSet left, VirtualChangeSet right) => Equals(left, right); - public static bool operator !=(VirtualChangeSet left, VirtualChangeSet right) - { - return !Equals(left, right); - } + public static bool operator !=(VirtualChangeSet left, VirtualChangeSet right) => !Equals(left, right); public bool Equals(VirtualChangeSet? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -61,7 +55,7 @@ public override int GetHashCode() { unchecked { - int hashCode = Response.GetHashCode(); + var hashCode = Response.GetHashCode(); hashCode = (hashCode * 397) ^ SortedItems.GetHashCode(); return hashCode; } diff --git a/src/DynamicData/Cache/VirtualRequest.cs b/src/DynamicData/Cache/VirtualRequest.cs index b4d7db9df..242787e3d 100644 --- a/src/DynamicData/Cache/VirtualRequest.cs +++ b/src/DynamicData/Cache/VirtualRequest.cs @@ -78,12 +78,12 @@ public bool Equals(IVirtualRequest? x, IVirtualRequest? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } diff --git a/src/DynamicData/Cache/VirtualResponse.cs b/src/DynamicData/Cache/VirtualResponse.cs index 0838b8b86..c9398a4e4 100644 --- a/src/DynamicData/Cache/VirtualResponse.cs +++ b/src/DynamicData/Cache/VirtualResponse.cs @@ -55,7 +55,7 @@ public override int GetHashCode() { unchecked { - int hashCode = Size; + var hashCode = Size; hashCode = (hashCode * 397) ^ StartIndex; hashCode = (hashCode * 397) ^ TotalSize; return hashCode; @@ -79,12 +79,12 @@ public bool Equals(IVirtualResponse? x, IVirtualResponse? y) return true; } - if (ReferenceEquals(x, null)) + if (x is null) { return false; } - if (ReferenceEquals(y, null)) + if (y is null) { return false; } @@ -106,7 +106,7 @@ public int GetHashCode(IVirtualResponse? obj) unchecked { - int hashCode = obj.TotalSize; + var hashCode = obj.TotalSize; hashCode = (hashCode * 397) ^ obj.StartIndex; hashCode = (hashCode * 397) ^ obj.Size; return hashCode; diff --git a/src/DynamicData/Diagnostics/ChangeStatistics.cs b/src/DynamicData/Diagnostics/ChangeStatistics.cs index 28fb68b0c..0a1cc2c95 100644 --- a/src/DynamicData/Diagnostics/ChangeStatistics.cs +++ b/src/DynamicData/Diagnostics/ChangeStatistics.cs @@ -12,10 +12,7 @@ public class ChangeStatistics : IEquatable /// /// Initializes a new instance of the class. /// - public ChangeStatistics() - { - Index = -1; - } + public ChangeStatistics() => Index = -1; /// /// Initializes a new instance of the class. @@ -108,10 +105,7 @@ public ChangeStatistics(int index, int adds, int updates, int removes, int refre /// The left side to compare. /// The right side to compare. /// If the two sides are equal. - public static bool operator ==(ChangeStatistics left, ChangeStatistics right) - { - return Equals(left, right); - } + public static bool operator ==(ChangeStatistics left, ChangeStatistics right) => Equals(left, right); /// /// Checks to see if both sides are not equal. @@ -119,15 +113,12 @@ public ChangeStatistics(int index, int adds, int updates, int removes, int refre /// The left side to compare. /// The right side to compare. /// If the two sides are not equal. - public static bool operator !=(ChangeStatistics left, ChangeStatistics right) - { - return !Equals(left, right); - } + public static bool operator !=(ChangeStatistics left, ChangeStatistics right) => !Equals(left, right); /// public bool Equals(ChangeStatistics? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } diff --git a/src/DynamicData/Diagnostics/ChangeSummary.cs b/src/DynamicData/Diagnostics/ChangeSummary.cs index 18e14b7cc..f41b93680 100644 --- a/src/DynamicData/Diagnostics/ChangeSummary.cs +++ b/src/DynamicData/Diagnostics/ChangeSummary.cs @@ -58,7 +58,7 @@ private ChangeSummary() /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -76,7 +76,7 @@ public override int GetHashCode() { unchecked { - int hashCode = _index; + var hashCode = _index; hashCode = (hashCode * 397) ^ Latest.GetHashCode(); hashCode = (hashCode * 397) ^ Overall.GetHashCode(); return hashCode; diff --git a/src/DynamicData/Diagnostics/DiagnosticOperators.cs b/src/DynamicData/Diagnostics/DiagnosticOperators.cs index f7e9fec2e..b0ea4b22f 100644 --- a/src/DynamicData/Diagnostics/DiagnosticOperators.cs +++ b/src/DynamicData/Diagnostics/DiagnosticOperators.cs @@ -18,27 +18,24 @@ public static class DiagnosticOperators /// The type of the key. /// The source. /// An observable which emits the change summary. - /// source. + /// source. public static IObservable CollectUpdateStats(this IObservable> source) where TSource : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Scan( ChangeSummary.Empty, (seed, next) => { - int index = seed.Overall.Index + 1; - int adds = seed.Overall.Adds + next.Adds; - int updates = seed.Overall.Updates + next.Updates; - int removes = seed.Overall.Removes + next.Removes; - int evaluates = seed.Overall.Refreshes + next.Refreshes; - int moves = seed.Overall.Moves + next.Moves; - int total = seed.Overall.Count + next.Count; + var index = seed.Overall.Index + 1; + var adds = seed.Overall.Adds + next.Adds; + var updates = seed.Overall.Updates + next.Updates; + var removes = seed.Overall.Removes + next.Removes; + var evaluates = seed.Overall.Refreshes + next.Refreshes; + var moves = seed.Overall.Moves + next.Moves; + var total = seed.Overall.Count + next.Count; var latest = new ChangeStatistics(index, next.Adds, next.Updates, next.Removes, next.Refreshes, next.Moves, next.Count); var overall = new ChangeStatistics(index, adds, updates, removes, evaluates, moves, total); @@ -52,25 +49,22 @@ public static IObservable CollectUpdateStats(this /// The type of the source. /// The source. /// An observable which emits the change summary. - /// source. + /// source. public static IObservable CollectUpdateStats(this IObservable> source) where TSource : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Scan( ChangeSummary.Empty, (seed, next) => { - int index = seed.Overall.Index + 1; - int adds = seed.Overall.Adds + next.Adds; - int updates = seed.Overall.Updates + next.Replaced; - int removes = seed.Overall.Removes + next.Removes; - int moves = seed.Overall.Moves + next.Moves; - int total = seed.Overall.Count + next.Count; + var index = seed.Overall.Index + 1; + var adds = seed.Overall.Adds + next.Adds; + var updates = seed.Overall.Updates + next.Replaced; + var removes = seed.Overall.Removes + next.Removes; + var moves = seed.Overall.Moves + next.Moves; + var total = seed.Overall.Count + next.Count; var latest = new ChangeStatistics(index, next.Adds, next.Replaced, next.Removes, 0, next.Moves, next.Count); var overall = new ChangeStatistics(index, adds, updates, removes, 0, moves, total); diff --git a/src/DynamicData/EnumerableEx.cs b/src/DynamicData/EnumerableEx.cs index 93aa43f76..e1576df1c 100644 --- a/src/DynamicData/EnumerableEx.cs +++ b/src/DynamicData/EnumerableEx.cs @@ -23,28 +23,15 @@ public static class EnumerableEx /// The key selector. /// Optionally emit an OnComplete. /// An observable change set. - /// source + /// source /// or /// keySelector. public static IObservable> AsObservableChangeSet(this IEnumerable source, Func keySelector, bool completable = false) where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Observable.Create>( obs => @@ -69,18 +56,11 @@ public static IObservable> AsObservableChangeSetThe source. /// Optionally emit an OnComplete. /// An observable change set. - /// source. + /// source. public static IObservable> AsObservableChangeSet(this IEnumerable source, bool completable = false) where TObject : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(source); -#else - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } -#endif + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return Observable.Create>( obs => diff --git a/src/DynamicData/Experimental/ExperimentalEx.cs b/src/DynamicData/Experimental/ExperimentalEx.cs index c39224cfe..c574f9b0f 100644 --- a/src/DynamicData/Experimental/ExperimentalEx.cs +++ b/src/DynamicData/Experimental/ExperimentalEx.cs @@ -19,15 +19,12 @@ public static class ExperimentalEx /// The source. /// The scheduler. /// The watcher. - /// source. + /// source. public static IWatcher AsWatcher(this IObservable> source, IScheduler? scheduler = null) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new Watcher(source, scheduler ?? Scheduler.Default); } diff --git a/src/DynamicData/Internal/ExceptionMixins.cs b/src/DynamicData/Internal/ExceptionMixins.cs new file mode 100644 index 000000000..a537ec825 --- /dev/null +++ b/src/DynamicData/Internal/ExceptionMixins.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2011-2023 Roland Pheasant. All rights reserved. +// Roland Pheasant licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace DynamicData +{ + internal static class ExceptionMixins + { + public static void ThrowArgumentNullExceptionIfNull(this T? value, string name) + { + if (value is null) + { + throw new ArgumentNullException(name); + } + } + } +} diff --git a/src/DynamicData/Kernel/EnumerableEx.cs b/src/DynamicData/Kernel/EnumerableEx.cs index 1ae70cf89..186da84bb 100644 --- a/src/DynamicData/Kernel/EnumerableEx.cs +++ b/src/DynamicData/Kernel/EnumerableEx.cs @@ -17,10 +17,7 @@ public static class EnumerableEx /// The array of items. public static T[] AsArray(this IEnumerable source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source as T[] ?? source.ToArray(); } @@ -33,10 +30,7 @@ public static T[] AsArray(this IEnumerable source) /// The list. public static List AsList(this IEnumerable source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source as List ?? source.ToList(); } @@ -51,15 +45,8 @@ public static List AsList(this IEnumerable source) /// The enumerable of items. public static IEnumerable Duplicates(this IEnumerable source, Func valueSelector) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.GroupBy(valueSelector).Where(group => group.Count() > 1).SelectMany(t => t); } @@ -86,20 +73,9 @@ public static IEnumerable Duplicates(this IEnumerable source, F /// A result as specified by the result selector. public static IEnumerable IndexOfMany(this IEnumerable source, IEnumerable itemsToFind, Func resultSelector) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (itemsToFind is null) - { - throw new ArgumentNullException(nameof(itemsToFind)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + itemsToFind.ThrowArgumentNullExceptionIfNull(nameof(itemsToFind)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); var indexed = source.Select((element, index) => new { Element = element, Index = index }); return itemsToFind.Join(indexed, left => left, right => right.Element, (_, right) => right).Select(x => resultSelector(x.Element, x.Index)); @@ -122,7 +98,7 @@ internal static void ForEach(this IEnumerable source, Action action) internal static void ForEach(this IEnumerable source, Action action) { - int i = 0; + var i = 0; foreach (var item in source) { action(item, i); diff --git a/src/DynamicData/Kernel/EnumeratorIList.cs b/src/DynamicData/Kernel/EnumeratorIList.cs index c38104bdf..520799d77 100644 --- a/src/DynamicData/Kernel/EnumeratorIList.cs +++ b/src/DynamicData/Kernel/EnumeratorIList.cs @@ -8,14 +8,13 @@ // Lifted from here https://github.com/benaadams/Ben.Enumerable. Many thanks to the genius of the man. namespace DynamicData.Kernel; -[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Same class name, different generics.")] internal struct EnumeratorIList(IList list) : IEnumerator { private int _index = -1; - public T Current => list[_index]; + public readonly T Current => list[_index]; - object? IEnumerator.Current => Current; + readonly object? IEnumerator.Current => Current; public bool MoveNext() { diff --git a/src/DynamicData/Kernel/Error.cs b/src/DynamicData/Kernel/Error.cs index 4a0e515b4..8a1587f68 100644 --- a/src/DynamicData/Kernel/Error.cs +++ b/src/DynamicData/Kernel/Error.cs @@ -2,8 +2,6 @@ // Roland Pheasant licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -#pragma warning disable 1591 - namespace DynamicData.Kernel; /// @@ -17,6 +15,7 @@ namespace DynamicData.Kernel; /// The exception that caused the error. /// The value for the error. /// The key for the error. +[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "By Design.")] public sealed class Error(Exception? exception, TObject value, TKey key) : IKeyValue, IEquatable> where TKey : notnull { @@ -35,20 +34,14 @@ public sealed class Error(Exception? exception, TObject value, TK /// public TObject Value { get; } = value; - public static bool operator ==(Error left, Error right) - { - return Equals(left, right); - } + public static bool operator ==(Error left, Error right) => Equals(left, right); - public static bool operator !=(Error left, Error right) - { - return !Equals(left, right); - } + public static bool operator !=(Error left, Error right) => !Equals(left, right); /// public bool Equals(Error? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -64,7 +57,7 @@ public bool Equals(Error? other) /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -82,9 +75,9 @@ public override int GetHashCode() { unchecked { - int hashCode = EqualityComparer.Default.GetHashCode(Key); + var hashCode = EqualityComparer.Default.GetHashCode(Key); hashCode = (hashCode * 397) ^ (Value is null ? 0 : EqualityComparer.Default.GetHashCode(Value)); - hashCode = (hashCode * 397) ^ (Exception is not null ? Exception.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (Exception?.GetHashCode() ?? 0); return hashCode; } } diff --git a/src/DynamicData/Kernel/InternalEx.cs b/src/DynamicData/Kernel/InternalEx.cs index 918c95ffc..0e70d426d 100644 --- a/src/DynamicData/Kernel/InternalEx.cs +++ b/src/DynamicData/Kernel/InternalEx.cs @@ -33,7 +33,7 @@ IObservable Retry(int failureCount) => source.Catch( error => { - TimeSpan? delay = backOffStrategy(error, failureCount); + var delay = backOffStrategy(error, failureCount); if (!delay.HasValue) { return Observable.Throw(error); @@ -78,10 +78,7 @@ public static IDisposable ScheduleRecurringAction(this IScheduler scheduler, Tim /// A disposable that will stop the schedule. public static IDisposable ScheduleRecurringAction(this IScheduler scheduler, Func interval, Action action) { - if (interval is null) - { - throw new ArgumentNullException(nameof(interval)); - } + interval.ThrowArgumentNullExceptionIfNull(nameof(interval)); return scheduler.Schedule( interval(), @@ -95,12 +92,7 @@ public static IDisposable ScheduleRecurringAction(this IScheduler scheduler, Fun internal static void OnNext(this ISubject source) => source.OnNext(Unit.Default); - internal static void Swap(ref TSwap t1, ref TSwap t2) - { - TSwap temp = t1; - t1 = t2; - t2 = temp; - } + internal static void Swap(ref TSwap t1, ref TSwap t2) => (t2, t1) = (t1, t2); internal static IObservable ToUnit(this IObservable source) => source.Select(_ => Unit.Default); diff --git a/src/DynamicData/Kernel/ItemWithIndex.cs b/src/DynamicData/Kernel/ItemWithIndex.cs index 3eabdd92a..13a2bca86 100644 --- a/src/DynamicData/Kernel/ItemWithIndex.cs +++ b/src/DynamicData/Kernel/ItemWithIndex.cs @@ -30,19 +30,13 @@ public readonly struct ItemWithIndex(T item, int index) : IEquatableThe first value to compare. /// The second value to compare. /// true if the and parameters have the same value; otherwise, false. - public static bool operator ==(ItemWithIndex left, ItemWithIndex right) - { - return left.Equals(right); - } + public static bool operator ==(in ItemWithIndex left, in ItemWithIndex right) => left.Equals(right); /// Returns a value that indicates whether two objects have different values. /// The first value to compare. /// The second value to compare. /// true if and are not equal; otherwise, false. - public static bool operator !=(ItemWithIndex left, ItemWithIndex right) - { - return !left.Equals(right); - } + public static bool operator !=(in ItemWithIndex left, in ItemWithIndex right) => !left.Equals(right); /// public bool Equals(ItemWithIndex other) => EqualityComparer.Default.Equals(Item, other.Item); @@ -50,7 +44,7 @@ public readonly struct ItemWithIndex(T item, int index) : IEquatable public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/Kernel/ItemWithValue.cs b/src/DynamicData/Kernel/ItemWithValue.cs index aeb050503..9f4309993 100644 --- a/src/DynamicData/Kernel/ItemWithValue.cs +++ b/src/DynamicData/Kernel/ItemWithValue.cs @@ -35,10 +35,7 @@ public readonly struct ItemWithValue(TObject item, TValue value /// /// The result of the operator. /// - public static bool operator ==(ItemWithValue left, ItemWithValue right) - { - return Equals(left, right); - } + public static bool operator ==(in ItemWithValue left, in ItemWithValue right) => Equals(left, right); /// /// Implements the operator !=. @@ -48,10 +45,7 @@ public readonly struct ItemWithValue(TObject item, TValue value /// /// The result of the operator. /// - public static bool operator !=(ItemWithValue left, ItemWithValue right) - { - return !Equals(left, right); - } + public static bool operator !=(in ItemWithValue left, in ItemWithValue right) => !Equals(left, right); /// public bool Equals(ItemWithValue other) => EqualityComparer.Default.Equals(Item, other.Item) && EqualityComparer.Default.Equals(Value, other.Value); @@ -59,7 +53,7 @@ public readonly struct ItemWithValue(TObject item, TValue value /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/Kernel/OptionElse.cs b/src/DynamicData/Kernel/OptionElse.cs index 9811fb8b7..8ac8d2f75 100644 --- a/src/DynamicData/Kernel/OptionElse.cs +++ b/src/DynamicData/Kernel/OptionElse.cs @@ -13,22 +13,16 @@ public sealed class OptionElse private readonly bool _shouldRunAction; - internal OptionElse(bool shouldRunAction = true) - { - _shouldRunAction = shouldRunAction; - } + internal OptionElse(bool shouldRunAction = true) => _shouldRunAction = shouldRunAction; /// /// Invokes the specified action when an option has no value. /// /// The action. - /// action. + /// action. public void Else(Action action) { - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + action.ThrowArgumentNullExceptionIfNull(nameof(action)); if (_shouldRunAction) { diff --git a/src/DynamicData/Kernel/OptionExtensions.cs b/src/DynamicData/Kernel/OptionExtensions.cs index 5ef18d9f2..f0598a692 100644 --- a/src/DynamicData/Kernel/OptionExtensions.cs +++ b/src/DynamicData/Kernel/OptionExtensions.cs @@ -2,6 +2,8 @@ // Roland Pheasant licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using System.Linq; + namespace DynamicData.Kernel; /// @@ -17,15 +19,12 @@ public static class OptionExtensions /// The source. /// The converter. /// The converted value. - /// converter. - public static Optional Convert(this Optional source, Func converter) + /// converter. + public static Optional Convert(this in Optional source, Func converter) where TSource : notnull where TDestination : notnull { - if (converter is null) - { - throw new ArgumentNullException(nameof(converter)); - } + converter.ThrowArgumentNullExceptionIfNull(nameof(converter)); return source.HasValue ? converter(source.Value) : Optional.None(); } @@ -38,15 +37,12 @@ public static Optional Convert(this Optiona /// The source. /// The converter that returns an optional value. /// The converted value. - /// converter. - public static Optional Convert(this Optional source, Func> converter) + /// converter. + public static Optional Convert(this in Optional source, Func> converter) where TSource : notnull where TDestination : notnull { - if (converter is null) - { - throw new ArgumentNullException(nameof(converter)); - } + converter.ThrowArgumentNullExceptionIfNull(nameof(converter)); return source.HasValue ? converter(source.Value) : Optional.None(); } @@ -60,23 +56,16 @@ public static Optional Convert(this Optiona /// The converter. /// The fallback converter. /// The destination value. - /// + /// /// converter /// or /// fallbackConverter. /// - public static TDestination? ConvertOr(this Optional source, Func converter, Func fallbackConverter) + public static TDestination? ConvertOr(this in Optional source, Func converter, Func fallbackConverter) where TSource : notnull { - if (converter is null) - { - throw new ArgumentNullException(nameof(converter)); - } - - if (fallbackConverter is null) - { - throw new ArgumentNullException(nameof(fallbackConverter)); - } + converter.ThrowArgumentNullExceptionIfNull(nameof(converter)); + fallbackConverter.ThrowArgumentNullExceptionIfNull(nameof(fallbackConverter)); return source.HasValue ? converter(source.Value) : fallbackConverter(); } @@ -88,18 +77,15 @@ public static Optional Convert(this Optiona /// The source. /// The fallback operation. /// The original value or the result of the fallback operation. - /// + /// /// converter /// or /// fallbackOperation. /// - public static Optional OrElse(this Optional source, Func> fallbackOperation) + public static Optional OrElse(this in Optional source, Func> fallbackOperation) where T : notnull { - if (fallbackOperation is null) - { - throw new ArgumentNullException(nameof(fallbackOperation)); - } + fallbackOperation.ThrowArgumentNullExceptionIfNull(nameof(fallbackOperation)); return source.HasValue ? source : fallbackOperation(); } @@ -116,17 +102,12 @@ public static Optional OrElse(this Optional source, Func> f public static Optional FirstOrOptional(this IEnumerable source, Func selector) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + selector.ThrowArgumentNullExceptionIfNull(nameof(selector)); - foreach (T item in source) + foreach (var item in source.Where(item => selector(item))) { - if (selector(item)) - { - return Optional.Create(item); - } + return Optional.Create(item); } return Optional.None(); @@ -139,7 +120,7 @@ public static Optional FirstOrOptional(this IEnumerable source, FuncThe source. /// The action. /// The optional else extension. - public static OptionElse IfHasValue(this Optional source, Action action) + public static OptionElse IfHasValue(this in Optional source, Action action) where T : notnull { if (!source.HasValue || source.Value is null) @@ -147,10 +128,7 @@ public static OptionElse IfHasValue(this Optional source, Action action return new OptionElse(); } - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + action.ThrowArgumentNullExceptionIfNull(nameof(action)); action(source.Value); return OptionElse.NoAction; @@ -176,10 +154,7 @@ public static OptionElse IfHasValue(this Optional? source, Action actio return new OptionElse(); } - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + action.ThrowArgumentNullExceptionIfNull(nameof(action)); action(source.Value.Value); return OptionElse.NoAction; @@ -198,12 +173,9 @@ public static OptionElse IfHasValue(this Optional? source, Action actio public static Optional Lookup(this IDictionary source, TKey key) where TValue : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - bool result = source.TryGetValue(key, out var contained); + var result = source.TryGetValue(key, out var contained); return result ? contained : Optional.None(); } @@ -217,10 +189,7 @@ public static Optional Lookup(this IDictionaryIf the item was removed. public static bool RemoveIfContained(this IDictionary source, TKey key) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.ContainsKey(key) && source.Remove(key); } @@ -252,14 +221,11 @@ public static T ValueOr(this T? source, T defaultValue) /// The source. /// The value selector. /// If the value or a provided default. - /// valueSelector. - public static T ValueOr(this Optional source, Func valueSelector) + /// valueSelector. + public static T ValueOr(this in Optional source, Func valueSelector) where T : notnull { - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return source.HasValue ? source.Value : valueSelector(); } @@ -270,7 +236,7 @@ public static T ValueOr(this Optional source, Func valueSelector) /// The type of the item. /// The source. /// The value or default. - public static T? ValueOrDefault(this Optional source) + public static T? ValueOrDefault(this in Optional source) where T : notnull { if (source.HasValue) @@ -288,14 +254,11 @@ public static T ValueOr(this Optional source, Func valueSelector) /// The source. /// The exception generator. /// The value. - /// exceptionGenerator. - public static T ValueOrThrow(this Optional source, Func exceptionGenerator) + /// exceptionGenerator. + public static T ValueOrThrow(this in Optional source, Func exceptionGenerator) where T : notnull { - if (exceptionGenerator is null) - { - throw new ArgumentNullException(nameof(exceptionGenerator)); - } + exceptionGenerator.ThrowArgumentNullExceptionIfNull(nameof(exceptionGenerator)); if (source.HasValue && source.Value is not null) { diff --git a/src/DynamicData/Kernel/OptionObservableExtensions.cs b/src/DynamicData/Kernel/OptionObservableExtensions.cs index ddec33a53..94e51bffa 100644 --- a/src/DynamicData/Kernel/OptionObservableExtensions.cs +++ b/src/DynamicData/Kernel/OptionObservableExtensions.cs @@ -20,21 +20,14 @@ public static class OptionObservableExtensions /// The source. /// The converter. /// Observable Optional of . - /// Source or Converter was null. - /// Observable version of . + /// Source or Converter was null. + /// Observable version of . public static IObservable> Convert(this IObservable> source, Func converter) where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (converter is null) - { - throw new ArgumentNullException(nameof(converter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + converter.ThrowArgumentNullExceptionIfNull(nameof(converter)); return source.Select(optional => optional.HasValue ? converter(optional.Value) : Optional.None()); } @@ -48,21 +41,14 @@ public static IObservable> Convert /// The source. /// The converter that returns an optional value. /// Observable Optional of . - /// Source or Converter was null. - /// Observable version of . + /// Source or Converter was null. + /// Observable version of . public static IObservable> Convert(this IObservable> source, Func> converter) where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (converter is null) - { - throw new ArgumentNullException(nameof(converter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + converter.ThrowArgumentNullExceptionIfNull(nameof(converter)); return source.Select(optional => optional.HasValue ? converter(optional.Value) : Optional.None()); } @@ -77,7 +63,7 @@ public static IObservable> Convert /// The converter. /// The fallback converter. /// Observable of . - /// + /// /// source /// or /// converter @@ -87,20 +73,9 @@ public static IObservable> Convert public static IObservable ConvertOr(this IObservable> source, Func converter, Func fallbackConverter) where TSource : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (converter is null) - { - throw new ArgumentNullException(nameof(converter)); - } - - if (fallbackConverter is null) - { - throw new ArgumentNullException(nameof(fallbackConverter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + converter.ThrowArgumentNullExceptionIfNull(nameof(converter)); + fallbackConverter.ThrowArgumentNullExceptionIfNull(nameof(fallbackConverter)); return source.Select(optional => optional.HasValue ? converter(optional.Value) : fallbackConverter()); } @@ -112,24 +87,17 @@ public static IObservable> Convert /// The source. /// The fallback operation. /// An Observable Optional that contains the Optionals with Values or the results of the fallback operation. - /// + /// /// source /// or - /// fallbackOperation. - /// - /// Observable version of . + /// fallbackOperation. + /// + /// Observable version of . public static IObservable> OrElse(this IObservable> source, Func> fallbackOperation) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (fallbackOperation is null) - { - throw new ArgumentNullException(nameof(fallbackOperation)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + fallbackOperation.ThrowArgumentNullExceptionIfNull(nameof(fallbackOperation)); return source.Select(optional => optional.HasValue ? optional : fallbackOperation()); } @@ -142,19 +110,12 @@ public static IObservable> OrElse(this IObservable> s /// The action. /// Optional alternative action for the Else case. /// The same Observable Optional. - /// Observable version of . + /// Observable version of . public static IObservable> OnHasValue(this IObservable> source, Action action, Action? elseAction = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + action.ThrowArgumentNullExceptionIfNull(nameof(action)); return source.Do(optional => optional.IfHasValue(action).Else(() => elseAction?.Invoke())); } @@ -170,15 +131,8 @@ public static IObservable> OnHasValue(this IObservable> OnHasNoValue(this IObservable> source, Action action, Action? elseAction = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + action.ThrowArgumentNullExceptionIfNull(nameof(action)); return source.Do(optional => optional.IfHasValue(val => elseAction?.Invoke(val)).Else(action)); } @@ -202,15 +156,12 @@ public static IObservable SelectValues(this IObservable> sourc /// The source. /// The value selector. /// If the value or a provided default. - /// valueSelector. - /// Observable version of . + /// valueSelector. + /// Observable version of . public static IObservable ValueOr(this IObservable> source, Func valueSelector) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select(optional => optional.HasValue ? optional.Value : valueSelector()); } @@ -221,14 +172,11 @@ public static IObservable ValueOr(this IObservable> source, Fu /// The type of the item. /// The source. /// The value or default. - /// Observable version of . + /// Observable version of . public static IObservable ValueOrDefault(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select(optional => optional.ValueOrDefault()); } @@ -241,20 +189,14 @@ public static IObservable ValueOr(this IObservable> source, Fu /// The source. /// The exception generator. /// The value. - /// exceptionGenerator. - /// Observable version of . + /// exceptionGenerator. + /// Observable version of . public static IObservable ValueOrThrow(this IObservable> source, Func exceptionGenerator) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (exceptionGenerator is null) - { - throw new ArgumentNullException(nameof(exceptionGenerator)); - } + exceptionGenerator.ThrowArgumentNullExceptionIfNull(nameof(exceptionGenerator)); return Observable.Create(observer => source.Subscribe( diff --git a/src/DynamicData/Kernel/Optional.cs b/src/DynamicData/Kernel/Optional.cs index 388d4f0f0..c0ab13f36 100644 --- a/src/DynamicData/Kernel/Optional.cs +++ b/src/DynamicData/Kernel/Optional.cs @@ -4,8 +4,6 @@ using System.Diagnostics.CodeAnalysis; -#pragma warning disable 1591 - namespace DynamicData.Kernel; /// @@ -25,7 +23,7 @@ namespace DynamicData.Kernel; /// The value. internal Optional(T? value) { - if (ReferenceEquals(value, null)) + if (value is null) { HasValue = false; _value = default; @@ -84,11 +82,11 @@ public T Value /// /// The value. /// The optional value. - public static explicit operator T?(Optional value) => FromOptional(value); + public static explicit operator T?(in Optional value) => FromOptional(value); - public static bool operator ==(Optional left, Optional right) => left.Equals(right); + public static bool operator ==(in Optional left, in Optional right) => left.Equals(right); - public static bool operator !=(Optional left, Optional right) => !left.Equals(right); + public static bool operator !=(in Optional left, in Optional right) => !left.Equals(right); /// /// Creates the specified value. @@ -102,7 +100,7 @@ public T Value /// /// The optional value. /// The value. - public static T? FromOptional(Optional value) => value.Value; + public static T? FromOptional(in Optional value) => value.Value; /// /// Gets the optional from a value. @@ -140,7 +138,7 @@ public bool Equals(Optional other) /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } @@ -177,6 +175,7 @@ public override int GetHashCode() /// /// Optional factory class. /// +[SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "By Design.")] public static class Optional { /// diff --git a/src/DynamicData/Kernel/ParallelEx.cs b/src/DynamicData/Kernel/ParallelEx.cs index 1a07fb6a3..e7f364c7b 100644 --- a/src/DynamicData/Kernel/ParallelEx.cs +++ b/src/DynamicData/Kernel/ParallelEx.cs @@ -8,18 +8,10 @@ namespace DynamicData.Kernel; internal static class ParallelEx { - [SuppressMessage("Design", "CA2000: Dispose SemaphoreSlim", Justification = "Captured in lambda, can cause problems.")] public static async Task> SelectParallel(this IEnumerable source, Func> selector, int maximumThreads = 5) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (selector is null) - { - throw new ArgumentNullException(nameof(selector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + selector.ThrowArgumentNullExceptionIfNull(nameof(selector)); var semaphore = new SemaphoreSlim(maximumThreads); var tasks = new List>(); diff --git a/src/DynamicData/Kernel/ReadOnlyCollectionLight.cs b/src/DynamicData/Kernel/ReadOnlyCollectionLight.cs index a7b9681b6..494e3bdb1 100644 --- a/src/DynamicData/Kernel/ReadOnlyCollectionLight.cs +++ b/src/DynamicData/Kernel/ReadOnlyCollectionLight.cs @@ -16,10 +16,7 @@ public ReadOnlyCollectionLight(IEnumerable items) Count = _items.Count; } - private ReadOnlyCollectionLight() - { - _items = new List(); - } + private ReadOnlyCollectionLight() => _items = new List(); public static IReadOnlyCollection Empty { get; } = new ReadOnlyCollectionLight(); diff --git a/src/DynamicData/List/Change.cs b/src/DynamicData/List/Change.cs index a3daf74c0..9bffe6d13 100644 --- a/src/DynamicData/List/Change.cs +++ b/src/DynamicData/List/Change.cs @@ -54,7 +54,7 @@ public Change(ListChangeReason reason, IEnumerable items, int index = -1) /// The current. /// The CurrentIndex. /// CurrentIndex of the previous. - /// + /// /// CurrentIndex must be greater than or equal to zero /// or /// PreviousIndex must be greater than or equal to zero. @@ -90,7 +90,7 @@ public Change(T current, int currentIndex, int previousIndex) /// or /// For ChangeReason.Change, must supply previous value. /// - public Change(ListChangeReason reason, T current, Optional previous, int currentIndex = -1, int previousIndex = -1) + public Change(ListChangeReason reason, T current, in Optional previous, int currentIndex = -1, int previousIndex = -1) { if (reason == ListChangeReason.Add && previous.HasValue) { @@ -142,7 +142,7 @@ public Change(ListChangeReason reason, T current, Optional previous, int curr /// public bool Equals(Change? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -158,7 +158,7 @@ public bool Equals(Change? other) /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/ChangeAwareList.cs b/src/DynamicData/List/ChangeAwareList.cs index 2b02bbd65..e727e2cc3 100644 --- a/src/DynamicData/List/ChangeAwareList.cs +++ b/src/DynamicData/List/ChangeAwareList.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for full license information. using System.Collections; - using DynamicData.Kernel; namespace DynamicData; @@ -13,23 +12,20 @@ namespace DynamicData; /// Used for creating custom operators. /// /// The item type. -/// +/// public class ChangeAwareList : IExtendedList where T : notnull { private readonly List _innerList; - - private ChangeSet _changes = new(); + private ChangeSet _changes = []; /// /// Initializes a new instance of the class. /// Create a change aware list with the specified capacity. /// /// The initial capacity of the internal lists. - public ChangeAwareList(int capacity = -1) - { - _innerList = capacity > 0 ? new List(capacity) : new List(); - } + public ChangeAwareList(int capacity = -1) => + _innerList = capacity > 0 ? new List(capacity) : []; /// /// Initializes a new instance of the class. @@ -38,10 +34,7 @@ public ChangeAwareList(int capacity = -1) /// The items to seed the change aware list with. public ChangeAwareList(IEnumerable items) { - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + items.ThrowArgumentNullExceptionIfNull(nameof(items)); var list = items.ToList(); @@ -61,10 +54,7 @@ public ChangeAwareList(IEnumerable items) /// Should the list of changes also be copied over?. public ChangeAwareList(ChangeAwareList list, bool copyChanges) { - if (list is null) - { - throw new ArgumentNullException(nameof(list)); - } + list.ThrowArgumentNullExceptionIfNull(nameof(list)); _innerList = new List(list._innerList); @@ -139,7 +129,9 @@ public void AddRange(IEnumerable collection) public IChangeSet CaptureChanges() { if (_changes.Count == 0) + { return ChangeSet.Empty; + } var returnValue = _changes; @@ -147,7 +139,7 @@ public IChangeSet CaptureChanges() if (_innerList.Count == 0 && returnValue.Removes == returnValue.TotalChanges && returnValue.TotalChanges > 1) { var removed = returnValue.Unified().Select(u => u.Current); - returnValue = new ChangeSet { new(ListChangeReason.Clear, removed) }; + returnValue = [new(ListChangeReason.Clear, removed)]; } ClearChanges(); @@ -161,7 +153,9 @@ public IChangeSet CaptureChanges() public virtual void Clear() { if (_innerList.Count == 0) + { return; + } var toRemove = _innerList.ToList(); @@ -214,7 +208,9 @@ public void Insert(int index, T item) } if (index > _innerList.Count) + { throw new ArgumentException($"{nameof(index)} cannot be greater than the size of the collection"); + } InsertItem(index, item); } @@ -229,7 +225,10 @@ public void Insert(int index, T item) public void InsertRange(IEnumerable collection, int index) { var args = new Change(ListChangeReason.AddRange, collection, index); - if (args.Range.Count == 0) return; + if (args.Range.Count == 0) + { + return; + } _changes.Add(args); _innerList.InsertRange(index, args.Range); @@ -245,14 +244,17 @@ public void InsertRange(IEnumerable collection, int index) public virtual void Move(T item, int destination) { if (destination < 0) + { throw new ArgumentException($"{nameof(destination)} cannot be negative"); + } if (destination > _innerList.Count) + { throw new ArgumentException($"{nameof(destination)} cannot be greater than the size of the collection"); + } - int index = _innerList.IndexOf(item); + var index = _innerList.IndexOf(item); Move(index, destination); - } /// @@ -263,16 +265,24 @@ public virtual void Move(T item, int destination) public virtual void Move(int original, int destination) { if (original < 0) + { throw new ArgumentException($"{nameof(original)} cannot be negative"); + } if (destination < 0) + { throw new ArgumentException($"{nameof(destination)} cannot be negative"); + } if (original > _innerList.Count) + { throw new ArgumentException($"{nameof(original)} cannot be greater than the size of the collection"); + } if (destination > _innerList.Count) + { throw new ArgumentException($"{nameof(destination)} cannot be greater than the size of the collection"); + } var item = _innerList[original]; _innerList.RemoveAt(original); @@ -294,7 +304,9 @@ public void Refresh(T item, int index) } if (index > _innerList.Count) + { throw new ArgumentException($"{nameof(index)} cannot be greater than the size of the collection"); + } var previous = _innerList[index]; _innerList[index] = item; @@ -312,7 +324,9 @@ public bool Refresh(T item) { var index = IndexOf(item); if (index < 0) + { return false; + } _changes.Add(new Change(ListChangeReason.Refresh, item, index)); @@ -327,7 +341,9 @@ public bool Refresh(T item) public void RefreshAt(int index) { if (index < 0) + { throw new ArgumentException($"{nameof(index)} cannot be negative"); + } if (index > _innerList.Count) { @@ -345,7 +361,10 @@ public void RefreshAt(int index) public bool Remove(T item) { var index = _innerList.IndexOf(item); - if (index < 0) return false; + if (index < 0) + { + return false; + } RemoveItem(index, item); return true; @@ -358,10 +377,14 @@ public bool Remove(T item) public void RemoveAt(int index) { if (index < 0) + { throw new ArgumentException($"{nameof(index)} cannot be negative"); + } if (index > _innerList.Count) + { throw new ArgumentOutOfRangeException(nameof(index), $"{nameof(index)} cannot be greater than the size of the collection"); + } RemoveItem(index); } @@ -397,7 +420,7 @@ public void RemoveRange(int index, int count) /// /// Clears the changes (for testing). /// - internal void ClearChanges() => _changes = new ChangeSet(); + internal void ClearChanges() => _changes = []; /// /// Inserts an item at the specified index. @@ -532,7 +555,9 @@ protected virtual void RemoveItem(int index, T item) } if (index > _innerList.Count) + { throw new ArgumentException($"{nameof(index)} cannot be greater than the size of the collection"); + } // attempt to batch updates as lists love to deal with ranges! (sorry if this code melts your mind) var last = Last; @@ -596,8 +621,15 @@ protected virtual void RemoveItem(int index, T item) /// The item to set. protected virtual void SetItem(int index, T item) { - if (index < 0) throw new ArgumentException($"{nameof(index)} cannot be negative"); - if (index > _innerList.Count) throw new ArgumentException($"{nameof(index)} cannot be greater than the size of the collection"); + if (index < 0) + { + throw new ArgumentException($"{nameof(index)} cannot be negative"); + } + + if (index > _innerList.Count) + { + throw new ArgumentException($"{nameof(index)} cannot be greater than the size of the collection"); + } var previous = _innerList[index]; _changes.Add(new Change(ListChangeReason.Replace, item, previous, index, index)); diff --git a/src/DynamicData/List/ChangeSet.cs b/src/DynamicData/List/ChangeSet.cs index 65f7174bd..42bf3b371 100644 --- a/src/DynamicData/List/ChangeSet.cs +++ b/src/DynamicData/List/ChangeSet.cs @@ -28,7 +28,7 @@ public ChangeSet() /// Initializes a new instance of the class. /// /// The items. - /// items. + /// items. public ChangeSet(IEnumerable> items) : base(items) { @@ -50,7 +50,7 @@ public int Adds { get { - int adds = 0; + var adds = 0; foreach (var item in this) { switch (item.Reason) @@ -86,7 +86,7 @@ public int Removes { get { - int removes = 0; + var removes = 0; foreach (var item in this) { switch (item.Reason) diff --git a/src/DynamicData/List/ChangeSetEx.cs b/src/DynamicData/List/ChangeSetEx.cs index 6224a2cd8..da11c6269 100644 --- a/src/DynamicData/List/ChangeSetEx.cs +++ b/src/DynamicData/List/ChangeSetEx.cs @@ -24,10 +24,7 @@ public static class ChangeSetEx public static IEnumerable> Flatten(this IChangeSet source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new ItemChangeEnumerator(source); } @@ -37,26 +34,12 @@ public static IEnumerable> Flatten(this IChangeSet source) /// /// The source. /// The change type. - public static ChangeType GetChangeType(this ListChangeReason source) + public static ChangeType GetChangeType(this ListChangeReason source) => source switch { - switch (source) - { - case ListChangeReason.Add: - case ListChangeReason.Refresh: - case ListChangeReason.Replace: - case ListChangeReason.Moved: - case ListChangeReason.Remove: - return ChangeType.Item; - - case ListChangeReason.AddRange: - case ListChangeReason.RemoveRange: - case ListChangeReason.Clear: - return ChangeType.Range; - - default: - throw new ArgumentOutOfRangeException(nameof(source)); - } - } + ListChangeReason.Add or ListChangeReason.Refresh or ListChangeReason.Replace or ListChangeReason.Moved or ListChangeReason.Remove => ChangeType.Item, + ListChangeReason.AddRange or ListChangeReason.RemoveRange or ListChangeReason.Clear => ChangeType.Range, + _ => throw new ArgumentOutOfRangeException(nameof(source)), + }; /// /// Transforms the change set into a different type using the specified transform function. @@ -75,15 +58,8 @@ public static IChangeSet Transform(this ICh where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformer is null) - { - throw new ArgumentNullException(nameof(transformer)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformer.ThrowArgumentNullExceptionIfNull(nameof(transformer)); var changes = source.Select( change => @@ -106,7 +82,12 @@ public static IChangeSet Transform(this ICh /// The source. /// An enumerable of changes. public static IEnumerable> YieldWithoutIndex(this IEnumerable> source) - where T : notnull => new WithoutIndexEnumerator(source); + where T : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + + return new WithoutIndexEnumerator(source); + } /// /// Returns a flattened source. @@ -118,10 +99,7 @@ public static IEnumerable> YieldWithoutIndex(this IEnumerable> Unified(this IChangeSet source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new UnifiedChangeEnumerator(source); } diff --git a/src/DynamicData/List/IChangeSetAdaptor.cs b/src/DynamicData/List/IChangeSetAdaptor.cs index 2dfbd65e2..71442a0d0 100644 --- a/src/DynamicData/List/IChangeSetAdaptor.cs +++ b/src/DynamicData/List/IChangeSetAdaptor.cs @@ -14,6 +14,6 @@ public interface IChangeSetAdaptor /// /// Adapts the specified change. /// - /// The change. - void Adapt(IChangeSet change); + /// The change. + void Adapt(IChangeSet changes); } diff --git a/src/DynamicData/List/IExtendedList.cs b/src/DynamicData/List/IExtendedList.cs index 4e1b1456e..6a425aa0a 100644 --- a/src/DynamicData/List/IExtendedList.cs +++ b/src/DynamicData/List/IExtendedList.cs @@ -24,7 +24,7 @@ public interface IExtendedList : IList /// The items to insert. /// The zero-based index at which the new elements should be inserted. /// is null. - /// is less than 0.-or- is greater than . + /// is less than 0.-or- is greater than . void InsertRange(IEnumerable collection, int index); /// diff --git a/src/DynamicData/List/Internal/AnonymousObservableList.cs b/src/DynamicData/List/Internal/AnonymousObservableList.cs index c9dec5974..4460c219c 100644 --- a/src/DynamicData/List/Internal/AnonymousObservableList.cs +++ b/src/DynamicData/List/Internal/AnonymousObservableList.cs @@ -11,15 +11,13 @@ namespace DynamicData.List.Internal; internal sealed class AnonymousObservableList : IObservableList where T : notnull { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "Disposed through _cleanUp")] private readonly ISourceList _sourceList; private readonly IDisposable _cleanUp; public AnonymousObservableList(IObservable> source) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); _sourceList = new SourceList(source); _cleanUp = _sourceList; diff --git a/src/DynamicData/List/Internal/AutoRefresh.cs b/src/DynamicData/List/Internal/AutoRefresh.cs index bf71e1b8a..0ceb73783 100644 --- a/src/DynamicData/List/Internal/AutoRefresh.cs +++ b/src/DynamicData/List/Internal/AutoRefresh.cs @@ -35,11 +35,8 @@ public IObservable> Run() => Observable.Create list.Count > 0); IObservable> requiresRefresh = itemsChanged.Synchronize(locker).Select( - items => - { - // catch all the indices of items which have been refreshed - return allItems.IndexOfMany(items, (t, idx) => new Change(ListChangeReason.Refresh, t, idx)); - }).Select(changes => new ChangeSet(changes)); + items => // catch all the indices of items which have been refreshed + allItems.IndexOfMany(items, (t, idx) => new Change(ListChangeReason.Refresh, t, idx))).Select(changes => new ChangeSet(changes)); // publish refreshes and underlying changes var publisher = shared.Merge(requiresRefresh).SubscribeSafe(observer); diff --git a/src/DynamicData/List/Internal/BufferIf.cs b/src/DynamicData/List/Internal/BufferIf.cs index cf0167336..06c22fbe2 100644 --- a/src/DynamicData/List/Internal/BufferIf.cs +++ b/src/DynamicData/List/Internal/BufferIf.cs @@ -55,7 +55,7 @@ public IObservable> Run() => Observable.Create>( } observer.OnNext(buffer); - buffer = new ChangeSet(); + buffer = []; // kill off timeout if required timeoutSubscriber.Disposable = Disposable.Empty; diff --git a/src/DynamicData/List/Internal/Combiner.cs b/src/DynamicData/List/Internal/Combiner.cs index 800dc2035..de777a870 100644 --- a/src/DynamicData/List/Internal/Combiner.cs +++ b/src/DynamicData/List/Internal/Combiner.cs @@ -131,6 +131,7 @@ private void UpdateItemMembership(T item, List> sourceL } } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208:Instantiate argument exceptions correctly", Justification = "By Design.")] private IChangeSet UpdateResultList(IChangeSet changes, List> sourceLists, ChangeAwareListWithRefCounts resultList) { // child caches have been updated before we reached this point. diff --git a/src/DynamicData/List/Internal/DisposeMany.cs b/src/DynamicData/List/Internal/DisposeMany.cs index 5fa0f7941..332f638e1 100644 --- a/src/DynamicData/List/Internal/DisposeMany.cs +++ b/src/DynamicData/List/Internal/DisposeMany.cs @@ -8,21 +8,16 @@ namespace DynamicData.List.Internal; -internal sealed class DisposeMany +internal sealed class DisposeMany(IObservable> source) where T : notnull { - private readonly IObservable> _source; - - public DisposeMany(IObservable> source) - => _source = source; - public IObservable> Run() => Observable.Create>(observer => { // Will be locking on cachedItems directly, instead of using an anonymous gate object. This is acceptable, since it's a privately-held object, there's no risk of deadlock from other consumers locking on it. var cachedItems = new List(); - var sourceSubscription = _source + var sourceSubscription = source .Synchronize(cachedItems) .SubscribeSafe(Observer.Create>( onNext: changeSet => @@ -35,7 +30,10 @@ public IObservable> Run() { case ListChangeReason.Clear: foreach (var item in cachedItems) + { (item as IDisposable)?.Dispose(); + } + break; case ListChangeReason.Remove: @@ -44,12 +42,18 @@ public IObservable> Run() case ListChangeReason.RemoveRange: foreach (var item in change.Range) + { (item as IDisposable)?.Dispose(); + } + break; case ListChangeReason.Replace: if (change.Item.Previous.HasValue) + { (change.Item.Previous.Value as IDisposable)?.Dispose(); + } + break; } } @@ -74,14 +78,18 @@ public IObservable> Run() sourceSubscription.Dispose(); lock (cachedItems) + { ProcessFinalization(cachedItems); + } }); }); private static void ProcessFinalization(List cachedItems) { foreach (var item in cachedItems) + { (item as IDisposable)?.Dispose(); + } cachedItems.Clear(); } diff --git a/src/DynamicData/List/Internal/Distinct.cs b/src/DynamicData/List/Internal/Distinct.cs index 08ba912d3..7287f395b 100644 --- a/src/DynamicData/List/Internal/Distinct.cs +++ b/src/DynamicData/List/Internal/Distinct.cs @@ -149,23 +149,17 @@ private sealed class ItemWithMatch(T item, TValue value, TValue? previousValue) /// The first value to compare. /// The second value to compare. /// true if the and parameters have the same value; otherwise, false. - public static bool operator ==(ItemWithMatch left, ItemWithMatch right) - { - return Equals(left, right); - } + public static bool operator ==(ItemWithMatch left, ItemWithMatch right) => Equals(left, right); /// Returns a value that indicates whether two objects have different values. /// The first value to compare. /// The second value to compare. /// true if and are not equal; otherwise, false. - public static bool operator !=(ItemWithMatch left, ItemWithMatch right) - { - return !Equals(left, right); - } + public static bool operator !=(ItemWithMatch left, ItemWithMatch right) => !Equals(left, right); public bool Equals(ItemWithMatch? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -180,7 +174,7 @@ public bool Equals(ItemWithMatch? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Internal/DynamicCombiner.cs b/src/DynamicData/List/Internal/DynamicCombiner.cs index 258f9ad74..44daed6be 100644 --- a/src/DynamicData/List/Internal/DynamicCombiner.cs +++ b/src/DynamicData/List/Internal/DynamicCombiner.cs @@ -142,6 +142,7 @@ private IChangeSet UpdateItemSetMemberships(MergeContainer[] sourceLists, Cha return resultingList.CaptureChanges(); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2208:Instantiate argument exceptions correctly", Justification = "By Design.")] private IChangeSet UpdateResultList(MergeContainer[] sourceLists, ChangeAwareListWithRefCounts resultList, IChangeSet changes) { // child caches have been updated before we reached this point. @@ -183,10 +184,7 @@ private IChangeSet UpdateResultList(MergeContainer[] sourceLists, ChangeAware private sealed class MergeContainer { - public MergeContainer(IObservable> source) - { - Source = source.Do(Clone); - } + public MergeContainer(IObservable> source) => Source = source.Do(Clone); public IObservable> Source { get; } diff --git a/src/DynamicData/List/Internal/ExpirableItem.cs b/src/DynamicData/List/Internal/ExpirableItem.cs index 2fdda391c..90da98574 100644 --- a/src/DynamicData/List/Internal/ExpirableItem.cs +++ b/src/DynamicData/List/Internal/ExpirableItem.cs @@ -12,19 +12,13 @@ internal sealed class ExpirableItem(TObject value, DateTime dateTime, l public TObject Item { get; } = value; - public static bool operator ==(ExpirableItem left, ExpirableItem right) - { - return Equals(left, right); - } + public static bool operator ==(ExpirableItem left, ExpirableItem right) => Equals(left, right); - public static bool operator !=(ExpirableItem left, ExpirableItem right) - { - return !Equals(left, right); - } + public static bool operator !=(ExpirableItem left, ExpirableItem right) => !Equals(left, right); public bool Equals(ExpirableItem? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -39,7 +33,7 @@ public bool Equals(ExpirableItem? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Internal/Filter.cs b/src/DynamicData/List/Internal/Filter.cs index f847440b3..c69db656a 100644 --- a/src/DynamicData/List/Internal/Filter.cs +++ b/src/DynamicData/List/Internal/Filter.cs @@ -53,7 +53,9 @@ public IObservable> Run() => Observable.Create>( else { if (_predicates is null) + { throw new InvalidOperationException("The predicates is not set and the change is not a immutableFilter."); + } predicateChanged = _predicates.Synchronize(locker).Select( newPredicate => @@ -70,17 +72,20 @@ public IObservable> Run() => Observable.Create>( */ // Need to get item by index and store it in the transform - var filteredResult = _source.Synchronize(locker).Transform((t, previous) => + var filteredResult = _source.Synchronize(locker).Transform( + (t, previous) => { var wasMatch = previous.ConvertOr(p => p!.IsMatch, () => false); return new ItemWithMatch(t, predicate(t), wasMatch); }, - true) + true) .Select(changes => { // keep track of all changes if filtering on an observable if (!immutableFilter) + { all.Clone(changes); + } return Process(filtered, changes); }); @@ -101,7 +106,9 @@ private static IChangeSet Process(ChangeAwareList { var change = item.Item; if (change.Current.IsMatch) + { filtered.Add(change.Current); + } break; } @@ -133,10 +140,9 @@ private static IChangeSet Process(ChangeAwareList filtered.Add(change.Current); } } - else + else if (wasMatch) { - if (wasMatch) - filtered.Remove(change.Previous.Value); + filtered.Remove(change.Previous.Value); } break; @@ -161,10 +167,9 @@ private static IChangeSet Process(ChangeAwareList filtered.Add(change.Current); } } - else + else if (wasMatch) { - if (wasMatch) - filtered.Remove(change.Current); + filtered.Remove(change.Current); } break; @@ -202,7 +207,7 @@ private IChangeSet Requery(Func predicate, List new ItemWithMatch(iwm.Item, predicate(iwm.Item), iwm.IsMatch)).ToList(); + var itemsWithMatch = all.ConvertAll(iwm => new ItemWithMatch(iwm.Item, predicate(iwm.Item), iwm.IsMatch)); // mark items as matched? filtered.Clear(); @@ -217,7 +222,7 @@ private IChangeSet Requery(Func predicate, List(all.Count); var toRemove = new List(all.Count); - for (int i = 0; i < all.Count; i++) + for (var i = 0; i < all.Count; i++) { var original = all[i]; @@ -243,7 +248,7 @@ private IChangeSet Requery(Func predicate, List + private sealed class ItemWithMatch(T item, bool isMatch, bool wasMatch = false) : IEquatable { public T Item { get; } = item; @@ -251,33 +256,49 @@ private class ItemWithMatch(T item, bool isMatch, bool wasMatch = false) : IEqua public bool WasMatch { get; set; } = wasMatch; + public static bool operator ==(ItemWithMatch? left, ItemWithMatch? right) => + Equals(left, right); + + public static bool operator !=(ItemWithMatch? left, ItemWithMatch? right) => + !Equals(left, right); + public bool Equals(ItemWithMatch? other) { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; + if (other is null) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + return EqualityComparer.Default.Equals(Item, other.Item); } public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((ItemWithMatch)obj); - } + if (obj is null) + { + return false; + } - public override int GetHashCode() => EqualityComparer.Default.GetHashCode(Item!); + if (ReferenceEquals(this, obj)) + { + return true; + } - public static bool operator ==(ItemWithMatch? left, ItemWithMatch? right) - { - return Equals(left, right); - } + if (obj.GetType() != GetType()) + { + return false; + } - public static bool operator !=(ItemWithMatch? left, ItemWithMatch? right) - { - return !Equals(left, right); + return Equals((ItemWithMatch)obj); } + public override int GetHashCode() => EqualityComparer.Default.GetHashCode(Item!); + public override string ToString() => $"{Item}, (was {IsMatch} is {WasMatch}"; } } diff --git a/src/DynamicData/List/Internal/FilterOnObservable.cs b/src/DynamicData/List/Internal/FilterOnObservable.cs index a67b8d811..fab810937 100644 --- a/src/DynamicData/List/Internal/FilterOnObservable.cs +++ b/src/DynamicData/List/Internal/FilterOnObservable.cs @@ -34,11 +34,8 @@ public IObservable> Run() => Observable.Create list.Count > 0); var requiresRefresh = itemsChanged.Synchronize(locker).Select( - items => - { - // catch all the indices of items which have been refreshed - return IndexOfMany(allItems, items, v => v.Obj, (t, idx) => new Change(ListChangeReason.Refresh, t, idx)); - }).Select(changes => new ChangeSet(changes)); + items => // catch all the indices of items which have been refreshed + IndexOfMany(allItems, items, v => v.Obj, (t, idx) => new Change(ListChangeReason.Refresh, t, idx))).Select(changes => new ChangeSet(changes)); // publish refreshes and underlying changes var publisher = shared.Merge(requiresRefresh).Filter(v => v.Filter) @@ -52,20 +49,9 @@ public IObservable> Run() => Observable.Create IndexOfMany(IEnumerable source, IEnumerable itemsToFind, Func objectPropertyFunc, Func resultSelector) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (itemsToFind is null) - { - throw new ArgumentNullException(nameof(itemsToFind)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + itemsToFind.ThrowArgumentNullExceptionIfNull(nameof(itemsToFind)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); var indexed = source.Select((element, index) => new { Element = element, Index = index }); return itemsToFind.Join(indexed, objectPropertyFunc, right => objectPropertyFunc(right.Element), (left, right) => resultSelector(left, right.Index)); diff --git a/src/DynamicData/List/Internal/FilterStatic.cs b/src/DynamicData/List/Internal/FilterStatic.cs index 69dab7d02..83ac36e4b 100644 --- a/src/DynamicData/List/Internal/FilterStatic.cs +++ b/src/DynamicData/List/Internal/FilterStatic.cs @@ -13,16 +13,13 @@ internal class FilterStatic(IObservable> source, Func private readonly IObservable> _source = source ?? throw new ArgumentNullException(nameof(source)); - public IObservable> Run() => Observable.Defer(() => - { - return _source.Scan( + public IObservable> Run() => Observable.Defer(() => _source.Scan( new ChangeAwareList(), (state, changes) => { Process(state, changes); return state; - }).Select(filtered => filtered.CaptureChanges()).NotEmpty(); - }); + }).Select(filtered => filtered.CaptureChanges()).NotEmpty()); private void Process(ChangeAwareList filtered, IChangeSet changes) { diff --git a/src/DynamicData/List/Internal/Group.cs b/src/DynamicData/List/Internal/Group.cs index 480aa4c59..4586c344a 100644 --- a/src/DynamicData/List/Internal/Group.cs +++ b/src/DynamicData/List/Internal/Group.cs @@ -11,17 +11,11 @@ internal class Group(TGroup groupKey) : IGroup public IObservableList List => Source; - private ISourceList Source { get; } = new SourceList(); + private SourceList Source { get; } = new(); - public static bool operator ==(Group left, Group right) - { - return Equals(left, right); - } + public static bool operator ==(Group left, Group right) => Equals(left, right); - public static bool operator !=(Group left, Group right) - { - return !Equals(left, right); - } + public static bool operator !=(Group left, Group right) => !Equals(left, right); public void Dispose() => Source.Dispose(); @@ -29,7 +23,7 @@ internal class Group(TGroup groupKey) : IGroup public bool Equals(Group? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } diff --git a/src/DynamicData/List/Internal/GroupOn.cs b/src/DynamicData/List/Internal/GroupOn.cs index 3838dcc13..25855aa18 100644 --- a/src/DynamicData/List/Internal/GroupOn.cs +++ b/src/DynamicData/List/Internal/GroupOn.cs @@ -34,11 +34,11 @@ public IObservable>> Run() => Observable.C var grouper = shared.Select(changes => Process(groupings, groupCache, changes)); - var regrouper = _regrouper is null ? + var regrouperFunc = _regrouper is null ? Observable.Never>>() : _regrouper.Synchronize(locker).CombineLatest(shared.ToCollection(), (_, collection) => Regroup(groupings, groupCache, collection)); - var publisher = grouper.Merge(regrouper).DisposeMany() // dispose removes as the grouping is disposable + var publisher = grouper.Merge(regrouperFunc).DisposeMany() // dispose removes as the grouping is disposable .NotEmpty().SubscribeSafe(observer); return new CompositeDisposable(publisher, shared.Connect()); @@ -248,23 +248,17 @@ private sealed class ItemWithGroupKey(TObject item, TGroupKey group, OptionalThe first value to compare. /// The second value to compare. /// true if the and parameters have the same value; otherwise, false. - public static bool operator ==(ItemWithGroupKey left, ItemWithGroupKey right) - { - return Equals(left, right); - } + public static bool operator ==(ItemWithGroupKey left, ItemWithGroupKey right) => Equals(left, right); /// Returns a value that indicates whether two objects have different values. /// The first value to compare. /// The second value to compare. /// true if and are not equal; otherwise, false. - public static bool operator !=(ItemWithGroupKey left, ItemWithGroupKey right) - { - return !Equals(left, right); - } + public static bool operator !=(ItemWithGroupKey left, ItemWithGroupKey right) => !Equals(left, right); public bool Equals(ItemWithGroupKey? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -279,7 +273,7 @@ public bool Equals(ItemWithGroupKey? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Internal/GroupOnImmutable.cs b/src/DynamicData/List/Internal/GroupOnImmutable.cs index 01eeb529e..f383c7a7f 100644 --- a/src/DynamicData/List/Internal/GroupOnImmutable.cs +++ b/src/DynamicData/List/Internal/GroupOnImmutable.cs @@ -37,11 +37,11 @@ public IObservable>> Run() => Observabl var grouper = shared.Select(changes => Process(groupings, groupCache, changes)); - IObservable>> reGrouper = _reGrouper is null ? + var reGroupFunc = _reGrouper is null ? Observable.Never>>() : _reGrouper.Synchronize(locker).CombineLatest(shared.ToCollection(), (_, collection) => Regroup(groupings, groupCache, collection)); - var publisher = grouper.Merge(reGrouper).NotEmpty().SubscribeSafe(observer); + var publisher = grouper.Merge(reGroupFunc).NotEmpty().SubscribeSafe(observer); return new CompositeDisposable(publisher, shared.Connect()); }); @@ -92,9 +92,9 @@ private static GroupContainer GetGroup(IDictionary gr return newcache; } - private static IGrouping GetGroupState(GroupContainer grouping) => new ImmutableGroup(grouping.Key, grouping.List); + private static ImmutableGroup GetGroupState(GroupContainer grouping) => new(grouping.Key, grouping.List); - private static IGrouping GetGroupState(TGroupKey key, IList list) => new ImmutableGroup(key, list); + private static ImmutableGroup GetGroupState(TGroupKey key, IList list) => new(key, list); private static IChangeSet> Process(ChangeAwareList> result, IDictionary allGroupings, IChangeSet changes) { @@ -136,7 +136,7 @@ void GetInitialState() var currentItem = change.Current.Item; // check whether an item changing has resulted in a different group - if (previousGroup.Equals(currentGroup) == false) + if (!previousGroup.Equals(currentGroup)) { GetInitialState(); @@ -252,7 +252,7 @@ private IChangeSet> Regroup(ChangeAwareList PreviousGroup { get; } = previousGroup; - public static bool operator ==(ItemWithGroupKey left, ItemWithGroupKey right) - { - return Equals(left, right); - } + public static bool operator ==(ItemWithGroupKey left, ItemWithGroupKey right) => Equals(left, right); - public static bool operator !=(ItemWithGroupKey left, ItemWithGroupKey right) - { - return !Equals(left, right); - } + public static bool operator !=(ItemWithGroupKey left, ItemWithGroupKey right) => !Equals(left, right); public bool Equals(ItemWithGroupKey? other) { diff --git a/src/DynamicData/List/Internal/ImmutableGroup.cs b/src/DynamicData/List/Internal/ImmutableGroup.cs index 84cc19cfc..413ce91d5 100644 --- a/src/DynamicData/List/Internal/ImmutableGroup.cs +++ b/src/DynamicData/List/Internal/ImmutableGroup.cs @@ -22,19 +22,13 @@ internal ImmutableGroup(TGroupKey key, IList items) public TGroupKey Key { get; } - public static bool operator ==(ImmutableGroup left, ImmutableGroup right) - { - return Equals(left, right); - } + public static bool operator ==(ImmutableGroup left, ImmutableGroup right) => Equals(left, right); - public static bool operator !=(ImmutableGroup left, ImmutableGroup right) - { - return !Equals(left, right); - } + public static bool operator !=(ImmutableGroup left, ImmutableGroup right) => !Equals(left, right); public bool Equals(ImmutableGroup? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -49,7 +43,7 @@ public bool Equals(ImmutableGroup? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Internal/Pager.cs b/src/DynamicData/List/Internal/Pager.cs index 6f04c112e..723d1cb83 100644 --- a/src/DynamicData/List/Internal/Pager.cs +++ b/src/DynamicData/List/Internal/Pager.cs @@ -48,8 +48,8 @@ private static int CalculatePages(ICollection all, IPageRequest? request) return 1; } - int pages = all.Count / request.Size; - int overlap = all.Count % request.Size; + var pages = all.Count / request.Size; + var overlap = all.Count % request.Size; if (overlap == 0) { @@ -78,9 +78,9 @@ private static PageChangeSet Page(List all, ChangeAwareList paged, IPag var previous = paged; - int pages = CalculatePages(all, request); - int page = request.Page > pages ? pages : request.Page; - int skip = request.Size * (page - 1); + var pages = CalculatePages(all, request); + var page = request.Page > pages ? pages : request.Page; + var skip = request.Size * (page - 1); var current = all.Distinct().Skip(skip) .Take(request.Size) @@ -101,15 +101,15 @@ private static PageChangeSet Page(List all, ChangeAwareList paged, IPag if (changeSet is not null && changeSet.Count != 0) { - var moves = changeSet + var changes = changeSet .Where(change => change.Reason == ListChangeReason.Moved - && change.MovedWithinRange(startIndex, startIndex + request.Size)); + && change.MovedWithinRange(startIndex, startIndex + request.Size)).Select(x => x.Item); - foreach (var change in moves) + foreach (var itemChange in changes) { // check whether an item has moved within the same page - var currentIndex = change.Item.CurrentIndex - startIndex; - var previousIndex = change.Item.PreviousIndex - startIndex; + var currentIndex = itemChange.CurrentIndex - startIndex; + var previousIndex = itemChange.PreviousIndex - startIndex; paged.Move(previousIndex, currentIndex); } } diff --git a/src/DynamicData/List/Internal/ReaderWriter.cs b/src/DynamicData/List/Internal/ReaderWriter.cs index 1d63d30ad..222eea63b 100644 --- a/src/DynamicData/List/Internal/ReaderWriter.cs +++ b/src/DynamicData/List/Internal/ReaderWriter.cs @@ -41,10 +41,7 @@ public T[] Items public IChangeSet Write(IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); IChangeSet result; @@ -59,10 +56,7 @@ public IChangeSet Write(IChangeSet changes) public IChangeSet Write(Action> updateAction) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); IChangeSet result; @@ -86,10 +80,7 @@ public IChangeSet Write(Action> updateAction) /// The action to perform on the list. public void WriteNested(Action> updateAction) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); lock (_locker) { @@ -104,15 +95,8 @@ public void WriteNested(Action> updateAction) public IChangeSet WriteWithPreview(Action> updateAction, Action> previewHandler) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } - - if (previewHandler is null) - { - throw new ArgumentNullException(nameof(previewHandler)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); + previewHandler.ThrowArgumentNullExceptionIfNull(nameof(previewHandler)); IChangeSet result; diff --git a/src/DynamicData/List/Internal/ReferenceCountTracker.cs b/src/DynamicData/List/Internal/ReferenceCountTracker.cs index 04a27e4c1..b9fed75f2 100644 --- a/src/DynamicData/List/Internal/ReferenceCountTracker.cs +++ b/src/DynamicData/List/Internal/ReferenceCountTracker.cs @@ -10,12 +10,11 @@ namespace DynamicData.List.Internal; /// /// The type of the item. internal class ReferenceCountTracker + where T : notnull { public IEnumerable Items => ReferenceCounts.Keys; -#pragma warning disable CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. - private Dictionary ReferenceCounts { get; } = new(); -#pragma warning restore CS8714 // The type cannot be used as type parameter in the generic type or method. Nullability of type argument doesn't match 'notnull' constraint. + private Dictionary ReferenceCounts { get; } = []; public int this[T item] => ReferenceCounts[item]; @@ -25,10 +24,7 @@ internal class ReferenceCountTracker /// The item to add. public bool Add(T item) { - if (item is null) - { - throw new ArgumentNullException(nameof(item)); - } + item.ThrowArgumentNullExceptionIfNull(nameof(item)); if (!ReferenceCounts.TryGetValue(item, out var currentCount)) { @@ -50,12 +46,9 @@ public bool Add(T item) /// The item to remove. public bool Remove(T item) { - if (item is null) - { - throw new ArgumentNullException(nameof(item)); - } + item.ThrowArgumentNullExceptionIfNull(nameof(item)); - int currentCount = ReferenceCounts[item]; + var currentCount = ReferenceCounts[item]; if (currentCount == 1) { diff --git a/src/DynamicData/List/Internal/Sort.cs b/src/DynamicData/List/Internal/Sort.cs index 6a9c7eea5..ba0abc39e 100644 --- a/src/DynamicData/List/Internal/Sort.cs +++ b/src/DynamicData/List/Internal/Sort.cs @@ -35,10 +35,10 @@ public IObservable> Run() => Observable.Create>( return changes.TotalChanges > resetThreshold ? Reset(original, target) : Process(target, changes); }); - var resort = _resort.Synchronize(locker).Select(_ => Reorder(target)); + var resortSync = _resort.Synchronize(locker).Select(_ => Reorder(target)); var changeComparer = _comparerObservable.Synchronize(locker).Select(comparer => ChangeComparer(target, comparer)); - return changeComparer.Merge(resort).Merge(dataChanged).Where(changes => changes.Count != 0).SubscribeSafe(observer); + return changeComparer.Merge(resortSync).Merge(dataChanged).Where(changes => changes.Count != 0).SubscribeSafe(observer); }); private IChangeSet ChangeComparer(ChangeAwareList target, IComparer comparer) @@ -71,8 +71,8 @@ private int GetCurrentPosition(ChangeAwareList target, T item) private int GetInsertPositionBinary(ChangeAwareList target, T item) { - int index = target.BinarySearch(item, _comparer); - int insertIndex = ~index; + var index = target.BinarySearch(item, _comparer); + var insertIndex = ~index; // sort is not returning uniqueness if (insertIndex < 0) @@ -199,7 +199,7 @@ private IChangeSet ProcessImpl(ChangeAwareList target, IChangeSet chang continue; } - int newPosition = GetInsertPositionLinear(target, item); + var newPosition = GetInsertPositionLinear(target, item); if (old < newPosition) { newPosition--; @@ -224,7 +224,7 @@ private void Remove(ChangeAwareList target, T item) private IChangeSet Reorder(ChangeAwareList target) { - int index = -1; + var index = -1; foreach (var item in target.OrderBy(t => t, _comparer).ToList()) { index++; diff --git a/src/DynamicData/List/Internal/TransformAsync.cs b/src/DynamicData/List/Internal/TransformAsync.cs index f18666d49..cd9ba7374 100644 --- a/src/DynamicData/List/Internal/TransformAsync.cs +++ b/src/DynamicData/List/Internal/TransformAsync.cs @@ -16,13 +16,12 @@ internal class TransformAsync private readonly IObservable> _source; private readonly bool _transformOnRefresh; - public TransformAsync(IObservable> source, - Func, int, Task> factory, bool transformOnRefresh) + public TransformAsync( + IObservable> source, + Func, int, Task> factory, + bool transformOnRefresh) { - if (factory is null) - { - throw new ArgumentNullException(nameof(factory)); - } + factory.ThrowArgumentNullExceptionIfNull(nameof(factory)); _source = source ?? throw new ArgumentNullException(nameof(source)); _transformOnRefresh = transformOnRefresh; @@ -65,10 +64,7 @@ private async Task Transform( ChangeAwareList.TransformedItemContainer> transformed, IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); foreach (var item in changes) { @@ -80,14 +76,18 @@ private async Task Transform( if (change.CurrentIndex < 0 || change.CurrentIndex >= transformed.Count) { var container = - await _containerFactory(item.Item.Current, Optional.None, + await _containerFactory( + item.Item.Current, + Optional.None, transformed.Count).ConfigureAwait(false); transformed.Add(container); } else { var container = - await _containerFactory(item.Item.Current, Optional.None, + await _containerFactory( + item.Item.Current, + Optional.None, change.CurrentIndex).ConfigureAwait(false); transformed.Insert(change.CurrentIndex, container); } diff --git a/src/DynamicData/List/Internal/TransformMany.cs b/src/DynamicData/List/Internal/TransformMany.cs index 0a05beb71..6993b8be5 100644 --- a/src/DynamicData/List/Internal/TransformMany.cs +++ b/src/DynamicData/List/Internal/TransformMany.cs @@ -158,6 +158,7 @@ public IEnumerator> GetEnumerator() switch (change.Reason) { case ListChangeReason.Add: + case ListChangeReason.Remove: foreach (var destination in change.Item.Current.Destination) { yield return new Change(change.Reason, destination); @@ -166,6 +167,7 @@ public IEnumerator> GetEnumerator() break; case ListChangeReason.AddRange: + case ListChangeReason.Clear: { var items = change.Range.SelectMany(m => m.Destination); yield return new Change(change.Reason, items); @@ -196,14 +198,6 @@ public IEnumerator> GetEnumerator() break; - case ListChangeReason.Remove: - foreach (var destination in change.Item.Current.Destination) - { - yield return new Change(change.Reason, destination); - } - - break; - case ListChangeReason.RemoveRange: { foreach (var destination in change.Range.SelectMany(m => m.Destination)) @@ -218,14 +212,6 @@ public IEnumerator> GetEnumerator() // do nothing as the original index has no bearing on the destination index break; - case ListChangeReason.Clear: - { - var items = change.Range.SelectMany(m => m.Destination); - yield return new Change(change.Reason, items); - } - - break; - default: throw new IndexOutOfRangeException("Unknown list reason " + change); } @@ -242,7 +228,7 @@ private sealed class ManyContainer(IEnumerable destination, IObser public IEnumerable Destination { get; } = destination; } - private class ManySelectorFunc(TSource source, Func> selector) : IEnumerable + private sealed class ManySelectorFunc(TSource source, Func> selector) : IEnumerable { private readonly Func> _selector = selector ?? throw new ArgumentNullException(nameof(selector)); diff --git a/src/DynamicData/List/Internal/Transformer.cs b/src/DynamicData/List/Internal/Transformer.cs index 12dc2e241..240082477 100644 --- a/src/DynamicData/List/Internal/Transformer.cs +++ b/src/DynamicData/List/Internal/Transformer.cs @@ -20,10 +20,7 @@ internal sealed class Transformer public Transformer(IObservable> source, Func, int, TDestination> factory, bool transformOnRefresh) { - if (factory is null) - { - throw new ArgumentNullException(nameof(factory)); - } + factory.ThrowArgumentNullExceptionIfNull(nameof(factory)); _source = source ?? throw new ArgumentNullException(nameof(source)); _transformOnRefresh = transformOnRefresh; @@ -45,10 +42,7 @@ private IObservable> RunImpl() => _source.Scan(new Chan private void Transform(ChangeAwareList transformed, IChangeSet changes) { - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); foreach (var item in changes) { @@ -57,7 +51,7 @@ private void Transform(ChangeAwareList transformed, IC case ListChangeReason.Add: { var change = item.Item; - if (change.CurrentIndex < 0 | change.CurrentIndex >= transformed.Count) + if (change.CurrentIndex < 0 || change.CurrentIndex >= transformed.Count) { transformed.Add(_containerFactory(change.Current, Optional.None, transformed.Count)); } @@ -143,7 +137,7 @@ TransformedItemContainer tic when transformed.IndexOf(tic) is int i and (>= 0) = case ListChangeReason.Remove: { var change = item.Item; - bool hasIndex = change.CurrentIndex >= 0; + var hasIndex = change.CurrentIndex >= 0; if (hasIndex) { @@ -189,7 +183,7 @@ TransformedItemContainer tic when transformed.IndexOf(tic) is int i and (>= 0) = case ListChangeReason.Moved: { var change = item.Item; - bool hasIndex = change.CurrentIndex >= 0; + var hasIndex = change.CurrentIndex >= 0; if (!hasIndex) { throw new UnspecifiedIndexException("Cannot move as an index was not specified"); @@ -214,7 +208,7 @@ internal sealed class TransformedItemContainer(TSource source, TDestination dest public bool Equals(TransformedItemContainer? other) { - if (ReferenceEquals(null, other)) + if (other is null) { return false; } @@ -229,7 +223,7 @@ public bool Equals(TransformedItemContainer? other) public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Internal/UnifiedChange.cs b/src/DynamicData/List/Internal/UnifiedChange.cs index 3471b9bb8..1ca53ab5d 100644 --- a/src/DynamicData/List/Internal/UnifiedChange.cs +++ b/src/DynamicData/List/Internal/UnifiedChange.cs @@ -20,21 +20,15 @@ public UnifiedChange(ListChangeReason reason, T current) public Optional Previous { get; } = previous; - public static bool operator ==(UnifiedChange left, UnifiedChange right) - { - return left.Equals(right); - } + public static bool operator ==(in UnifiedChange left, in UnifiedChange right) => left.Equals(right); - public static bool operator !=(UnifiedChange left, UnifiedChange right) - { - return !left.Equals(right); - } + public static bool operator !=(in UnifiedChange left, in UnifiedChange right) => !left.Equals(right); public bool Equals(UnifiedChange other) => Reason == other.Reason && EqualityComparer.Default.Equals(Current, other.Current) && Previous.Equals(other.Previous); public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Internal/Virtualiser.cs b/src/DynamicData/List/Internal/Virtualiser.cs index 3ca120728..4025fdb1c 100644 --- a/src/DynamicData/List/Internal/Virtualiser.cs +++ b/src/DynamicData/List/Internal/Virtualiser.cs @@ -72,13 +72,13 @@ private static IChangeSet Virtualise(IList all, ChangeAwareList virtual if (changeSet is not null && changeSet.Count != 0) { - var moves = changeSet.EmptyIfNull().Where(change => change.Reason == ListChangeReason.Moved && change.MovedWithinRange(request.StartIndex, request.StartIndex + request.Size)); + var changes = changeSet.EmptyIfNull().Where(change => change.Reason == ListChangeReason.Moved && change.MovedWithinRange(request.StartIndex, request.StartIndex + request.Size)).Select(x => x.Item); - foreach (var change in moves) + foreach (var itemChange in changes) { // check whether an item has moved within the same page - var currentIndex = change.Item.CurrentIndex - request.StartIndex; - var previousIndex = change.Item.PreviousIndex - request.StartIndex; + var currentIndex = itemChange.CurrentIndex - request.StartIndex; + var previousIndex = itemChange.PreviousIndex - request.StartIndex; virtualised.Move(previousIndex, currentIndex); } } diff --git a/src/DynamicData/List/ItemChange.cs b/src/DynamicData/List/ItemChange.cs index 3dcf07fc9..9432da5b7 100644 --- a/src/DynamicData/List/ItemChange.cs +++ b/src/DynamicData/List/ItemChange.cs @@ -27,7 +27,7 @@ namespace DynamicData; /// The previous. /// Value of the current. /// Value of the previous. - public ItemChange(ListChangeReason reason, T current, Optional previous, int currentIndex = -1, int previousIndex = -1) + public ItemChange(ListChangeReason reason, T current, in Optional previous, int currentIndex = -1, int previousIndex = -1) : this() { Reason = reason; @@ -86,7 +86,7 @@ public ItemChange(ListChangeReason reason, T current, int currentIndex) /// The left hand side to compare. /// The right hand side to compare. /// If the two values are equal. - public static bool operator ==(ItemChange left, ItemChange right) => left.Equals(right); + public static bool operator ==(in ItemChange left, in ItemChange right) => left.Equals(right); /// /// Determines whether the specified objects are not equal. @@ -94,7 +94,7 @@ public ItemChange(ListChangeReason reason, T current, int currentIndex) /// The left hand side to compare. /// The right hand side to compare. /// If the two values are not equal. - public static bool operator !=(ItemChange left, ItemChange right) => !left.Equals(right); + public static bool operator !=(in ItemChange left, in ItemChange right) => !left.Equals(right); /// /// Determines whether the specified object, is equal to this instance. @@ -112,7 +112,7 @@ public ItemChange(ListChangeReason reason, T current, int currentIndex) /// public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } diff --git a/src/DynamicData/List/Linq/ItemChangeEnumerator.cs b/src/DynamicData/List/Linq/ItemChangeEnumerator.cs index c7a01253e..f575c24bc 100644 --- a/src/DynamicData/List/Linq/ItemChangeEnumerator.cs +++ b/src/DynamicData/List/Linq/ItemChangeEnumerator.cs @@ -33,9 +33,6 @@ public IEnumerator> GetEnumerator() break; case ListChangeReason.RemoveRange: - yield return new ItemChange(ListChangeReason.Remove, item, index); - break; - case ListChangeReason.Clear: yield return new ItemChange(ListChangeReason.Remove, item, index); break; diff --git a/src/DynamicData/List/ListEx.cs b/src/DynamicData/List/ListEx.cs index 848e96453..c6882ce2b 100644 --- a/src/DynamicData/List/ListEx.cs +++ b/src/DynamicData/List/ListEx.cs @@ -20,22 +20,15 @@ public static class ListEx /// The type of the item. /// The source. /// The items. - /// + /// /// source /// or /// items. /// public static void Add(this IList source, IEnumerable items) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); items.ForEach(source.Add); } @@ -49,15 +42,8 @@ public static void Add(this IList source, IEnumerable items) /// The index. public static void AddOrInsertRange(this IList source, IEnumerable items, int index) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); switch (source) { @@ -96,22 +82,15 @@ public static void AddOrInsertRange(this IList source, IEnumerable item /// The type of the item. /// The source. /// The items. - /// + /// /// source /// or /// items. /// public static void AddRange(this IList source, IEnumerable items) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); switch (source) { @@ -136,15 +115,8 @@ public static void AddRange(this IList source, IEnumerable items) /// The index. public static void AddRange(this IList source, IEnumerable items, int index) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); switch (source) { @@ -179,10 +151,7 @@ public static void AddRange(this IList source, IEnumerable items, int i /// The index of the specified value in the specified array, if value is found; otherwise, a negative number. public static int BinarySearch(this IList list, TItem value, IComparer comparer) { - if (comparer is null) - { - throw new ArgumentNullException(nameof(comparer)); - } + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); return list.BinarySearch(value, comparer.Compare); } @@ -199,23 +168,16 @@ public static int BinarySearch(this IList list, TItem value, IComp /// The index of the specified value in the specified array, if value is found; otherwise, a negative number. public static int BinarySearch(this IList list, TSearch value, Func comparer) { - if (list is null) - { - throw new ArgumentNullException(nameof(list)); - } - - if (comparer is null) - { - throw new ArgumentNullException(nameof(comparer)); - } + list.ThrowArgumentNullExceptionIfNull(nameof(list)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); - int lower = 0; - int upper = list.Count - 1; + var lower = 0; + var upper = list.Count - 1; while (lower <= upper) { - int middle = lower + ((upper - lower) / 2); - int comparisonResult = comparer(value, list[middle]); + var middle = lower + ((upper - lower) / 2); + var comparisonResult = comparer(value, list[middle]); if (comparisonResult < 0) { upper = middle - 1; @@ -239,7 +201,7 @@ public static int BinarySearch(this IList list, TSearch v /// The type of the item. /// The source. /// The changes. - /// + /// /// source /// or /// changes. @@ -254,7 +216,7 @@ public static void Clone(this IList source, IChangeSet changes) /// The source. /// The changes. /// An equality comparer to match items in the changes. - /// + /// /// source /// or /// changes. @@ -269,7 +231,7 @@ public static void Clone(this IList source, IChangeSet changes, IEquali /// The source. /// The changes. /// An equality comparer to match items in the changes. - /// + /// /// source /// or /// changes. @@ -277,15 +239,8 @@ public static void Clone(this IList source, IChangeSet changes, IEquali public static void Clone(this IList source, IEnumerable> changes, IEqualityComparer? equalityComparer) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (changes is null) - { - throw new ArgumentNullException(nameof(changes)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + changes.ThrowArgumentNullExceptionIfNull(nameof(changes)); foreach (var item in changes) { @@ -312,17 +267,10 @@ public static void Clone(this IList source, IEnumerable> changes /// The index. public static int IndexOf(this IEnumerable source, T item, IEqualityComparer equalityComparer) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + equalityComparer.ThrowArgumentNullExceptionIfNull(nameof(equalityComparer)); - if (equalityComparer is null) - { - throw new ArgumentNullException(nameof(equalityComparer)); - } - - int i = 0; + var i = 0; foreach (var candidate in source) { if (equalityComparer.Equals(item, candidate)) @@ -357,22 +305,15 @@ public static Optional> IndexOfOptional(this IEnumerable /// The type of the item. /// The source. /// The items. - /// + /// /// source /// or /// items. /// public static void Remove(this IList source, IEnumerable items) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (items is null) - { - throw new ArgumentNullException(nameof(items)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + items.ThrowArgumentNullExceptionIfNull(nameof(items)); items.ForEach(t => source.Remove(t)); } @@ -390,15 +331,8 @@ public static void RemoveMany(this IList source, IEnumerable itemsToRem across the source collection IndexOf lookups can result in very slow updates (especially for subsequent operators) */ - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (itemsToRemove is null) - { - throw new ArgumentNullException(nameof(itemsToRemove)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + itemsToRemove.ThrowArgumentNullExceptionIfNull(nameof(itemsToRemove)); var toRemoveArray = itemsToRemove.AsArray(); @@ -429,25 +363,14 @@ across the source collection IndexOf lookups can result in very slow updates /// The source. /// The original. /// The value to replace with. - /// source + /// source /// or /// items. public static void Replace(this IList source, T original, T replaceWith) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (original is null) - { - throw new ArgumentNullException(nameof(original)); - } - - if (replaceWith is null) - { - throw new ArgumentNullException(nameof(replaceWith)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + original.ThrowArgumentNullExceptionIfNull(nameof(original)); + replaceWith.ThrowArgumentNullExceptionIfNull(nameof(replaceWith)); var index = source.IndexOf(original); if (index == -1) @@ -466,30 +389,15 @@ public static void Replace(this IList source, T original, T replaceWith) /// The item which is to be replaced. If not in the list and argument exception will be thrown. /// The new item. /// The equality comparer to be used to find the original item in the list. - /// source + /// source /// or /// items. public static void Replace(this IList source, T original, T replaceWith, IEqualityComparer comparer) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (original is null) - { - throw new ArgumentNullException(nameof(original)); - } - - if (replaceWith is null) - { - throw new ArgumentNullException(nameof(replaceWith)); - } - - if (comparer is null) - { - throw new ArgumentNullException(nameof(comparer)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + original.ThrowArgumentNullExceptionIfNull(nameof(original)); + replaceWith.ThrowArgumentNullExceptionIfNull(nameof(replaceWith)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); var index = source.IndexOf(original); if (index == -1) @@ -512,20 +420,9 @@ public static void Replace(this IList source, T original, T replaceWith, I /// The value to replace with. public static void ReplaceOrAdd(this IList source, T original, T replaceWith) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (original is null) - { - throw new ArgumentNullException(nameof(original)); - } - - if (replaceWith is null) - { - throw new ArgumentNullException(nameof(replaceWith)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + original.ThrowArgumentNullExceptionIfNull(nameof(original)); + replaceWith.ThrowArgumentNullExceptionIfNull(nameof(replaceWith)); var index = source.IndexOf(original); if (index == -1) @@ -658,14 +555,14 @@ private static void Clone(this IList source, Change item, IEqualityComp case ListChangeReason.Remove: { var change = item.Item; - bool hasIndex = change.CurrentIndex >= 0; + var hasIndex = change.CurrentIndex >= 0; if (hasIndex) { source.RemoveAt(change.CurrentIndex); } else { - int index = source.IndexOf(change.Current, equalityComparer); + var index = source.IndexOf(change.Current, equalityComparer); if (index > -1) { source.RemoveAt(index); @@ -695,7 +592,7 @@ private static void Clone(this IList source, Change item, IEqualityComp case ListChangeReason.Moved: { var change = item.Item; - bool hasIndex = change.CurrentIndex >= 0; + var hasIndex = change.CurrentIndex >= 0; if (!hasIndex) { throw new UnspecifiedIndexException("Cannot move as an index was not specified"); @@ -728,13 +625,10 @@ private static void Clone(this IList source, Change item, IEqualityComp /// The source. /// The index. /// The count. - /// Cannot remove range. + /// Cannot remove range. private static void RemoveRange(this IList source, int index, int count) { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); switch (source) { diff --git a/src/DynamicData/List/ObservableListEx.cs b/src/DynamicData/List/ObservableListEx.cs index 1f52117e3..58fbf51e9 100644 --- a/src/DynamicData/List/ObservableListEx.cs +++ b/src/DynamicData/List/ObservableListEx.cs @@ -31,7 +31,7 @@ public static class ObservableListEx /// The source. /// The adaptor. /// An observable which emits the change set. - /// + /// /// source /// or /// adaptor. @@ -39,15 +39,8 @@ public static class ObservableListEx public static IObservable> Adapt(this IObservable> source, IChangeSetAdaptor adaptor) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (adaptor is null) - { - throw new ArgumentNullException(nameof(adaptor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + adaptor.ThrowArgumentNullExceptionIfNull(nameof(adaptor)); return Observable.Create>( observer => @@ -77,15 +70,8 @@ public static IObservable> AddKey(this where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return source.Select(changes => new ChangeSet(new AddKeyEnumerator(changes, keySelector))); } @@ -99,7 +85,12 @@ public static IObservable> AddKey(this /// The others. /// An observable which emits the change set. public static IObservable> And(this IObservable> source, params IObservable>[] others) - where T : notnull => source.Combine(CombineOperator.And, others); + where T : notnull + { + others.ThrowArgumentNullExceptionIfNull(nameof(others)); + + return source.Combine(CombineOperator.And, others); + } /// /// Apply a logical And operator between the collections. @@ -147,14 +138,11 @@ public static IObservable> And(this IObservableListThe type of the item. /// The source. /// An observable list. - /// source. + /// source. public static IObservableList AsObservableList(this ISourceList source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new AnonymousObservableList(source); } @@ -165,14 +153,11 @@ public static IObservableList AsObservableList(this ISourceList source) /// The type of the item. /// The source. /// An observable list. - /// source. + /// source. public static IObservableList AsObservableList(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new AnonymousObservableList(source); } @@ -189,10 +174,7 @@ public static IObservableList AsObservableList(this IObservable> AutoRefresh(this IObservable> source, TimeSpan? changeSetBuffer = null, TimeSpan? propertyChangeThrottle = null, IScheduler? scheduler = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.AutoRefreshOnObservable( t => @@ -222,15 +204,8 @@ public static IObservable> AutoRefresh(this IObserv public static IObservable> AutoRefresh(this IObservable> source, Expression> propertyAccessor, TimeSpan? changeSetBuffer = null, TimeSpan? propertyChangeThrottle = null, IScheduler? scheduler = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertyAccessor is null) - { - throw new ArgumentNullException(nameof(propertyAccessor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertyAccessor.ThrowArgumentNullExceptionIfNull(nameof(propertyAccessor)); return source.AutoRefreshOnObservable( t => @@ -259,15 +234,8 @@ public static IObservable> AutoRefresh(t public static IObservable> AutoRefreshOnObservable(this IObservable> source, Func> reevaluator, TimeSpan? changeSetBuffer = null, IScheduler? scheduler = null) where TObject : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (reevaluator is null) - { - throw new ArgumentNullException(nameof(reevaluator)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + reevaluator.ThrowArgumentNullExceptionIfNull(nameof(reevaluator)); return new AutoRefresh(source, reevaluator, changeSetBuffer, scheduler).Run(); } @@ -280,7 +248,7 @@ public static IObservable> AutoRefreshOnObservableThe target collection. /// The reset threshold. /// An observable which emits the change set. - /// + /// /// source /// or /// targetCollection. @@ -288,15 +256,8 @@ public static IObservable> AutoRefreshOnObservable> Bind(this IObservable> source, IObservableCollection targetCollection, int resetThreshold = BindingOptions.DefaultResetThreshold) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (targetCollection is null) - { - throw new ArgumentNullException(nameof(targetCollection)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + targetCollection.ThrowArgumentNullExceptionIfNull(nameof(targetCollection)); // if user has not specified different defaults, use system wide defaults instead. // This is a hack to retro fit system wide defaults which override the hard coded defaults above @@ -325,15 +286,8 @@ public static IObservable> Bind(this IObservable> public static IObservable> Bind(this IObservable> source, IObservableCollection targetCollection, BindingOptions options) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (targetCollection is null) - { - throw new ArgumentNullException(nameof(targetCollection)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + targetCollection.ThrowArgumentNullExceptionIfNull(nameof(targetCollection)); var adaptor = new ObservableCollectionAdaptor(targetCollection, options); return source.Adapt(adaptor); @@ -350,10 +304,7 @@ public static IObservable> Bind(this IObservable> public static IObservable> Bind(this IObservable> source, out ReadOnlyObservableCollection readOnlyObservableCollection, int resetThreshold = BindingOptions.DefaultResetThreshold) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); // if user has not specified different defaults, use system wide defaults instead. // This is a hack to retro fit system wide defaults which override the hard coded defaults above @@ -376,10 +327,7 @@ public static IObservable> Bind(this IObservable> public static IObservable> Bind(this IObservable> source, out ReadOnlyObservableCollection readOnlyObservableCollection, BindingOptions options) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); var target = new ObservableCollectionExtended(); var result = new ReadOnlyObservableCollection(target); @@ -397,7 +345,7 @@ public static IObservable> Bind(this IObservable> /// The source. /// The target binding list. /// The reset threshold. - /// + /// /// source /// or /// targetCollection. @@ -406,15 +354,8 @@ public static IObservable> Bind(this IObservable> public static IObservable> Bind(this IObservable> source, BindingList bindingList, int resetThreshold = BindingOptions.DefaultResetThreshold) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (bindingList is null) - { - throw new ArgumentNullException(nameof(bindingList)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + bindingList.ThrowArgumentNullExceptionIfNull(nameof(bindingList)); return source.Adapt(new BindingListAdaptor(bindingList, resetThreshold)); } @@ -430,7 +371,7 @@ public static IObservable> Bind(this IObservable> /// When true, observable begins to buffer and when false, window closes and buffered result if notified. /// The scheduler. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> BufferIf(this IObservable> source, IObservable pauseIfTrueSelector, IScheduler? scheduler = null) where T : notnull => BufferIf(source, pauseIfTrueSelector, false, scheduler); @@ -444,19 +385,12 @@ public static IObservable> BufferIf(this IObservableif set to true [initial pause state]. /// The scheduler. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> BufferIf(this IObservable> source, IObservable pauseIfTrueSelector, bool initialPauseState, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (pauseIfTrueSelector is null) - { - throw new ArgumentNullException(nameof(pauseIfTrueSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + pauseIfTrueSelector.ThrowArgumentNullExceptionIfNull(nameof(pauseIfTrueSelector)); return BufferIf(source, pauseIfTrueSelector, initialPauseState, null, scheduler); } @@ -471,7 +405,7 @@ public static IObservable> BufferIf(this IObservableSpecify a time to ensure the buffer window does not stay open for too long. /// The scheduler. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> BufferIf(this IObservable> source, IObservable pauseIfTrueSelector, TimeSpan? timeOut, IScheduler? scheduler = null) where T : notnull => BufferIf(source, pauseIfTrueSelector, false, timeOut, scheduler); @@ -486,19 +420,12 @@ public static IObservable> BufferIf(this IObservableSpecify a time to ensure the buffer window does not stay open for too long. /// The scheduler. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> BufferIf(this IObservable> source, IObservable pauseIfTrueSelector, bool initialPauseState, TimeSpan? timeOut, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (pauseIfTrueSelector is null) - { - throw new ArgumentNullException(nameof(pauseIfTrueSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + pauseIfTrueSelector.ThrowArgumentNullExceptionIfNull(nameof(pauseIfTrueSelector)); return new BufferIf(source, pauseIfTrueSelector, initialPauseState, timeOut, scheduler).Run(); } @@ -529,10 +456,7 @@ public static IObservable> BufferInitial(this IObse public static IObservable> Cast(this IObservable> source) where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select(changes => changes.Transform(t => (TDestination)t)); } @@ -550,15 +474,9 @@ public static IObservable> Cast( where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (conversionFactory is null) - { - throw new ArgumentNullException(nameof(conversionFactory)); - } + conversionFactory.ThrowArgumentNullExceptionIfNull(nameof(conversionFactory)); return source.Select(changes => changes.Transform(conversionFactory)); } @@ -579,14 +497,11 @@ public static IObservable> CastToObject(this IObservableThe source. /// The target of the clone. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> Clone(this IObservable> source, IList target) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Do(target.Clone); } @@ -605,15 +520,9 @@ public static IObservable> Convert changes.Transform(conversionFactory)); } @@ -627,10 +536,7 @@ public static IObservable> Convert> DeferUntilLoaded(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new DeferUntilLoaded(source).Run(); } @@ -644,10 +550,7 @@ public static IObservable> DeferUntilLoaded(this IObservable> DeferUntilLoaded(this IObservableList source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Connect().DeferUntilLoaded(); } @@ -662,12 +565,11 @@ public static IObservable> DeferUntilLoaded(this IObservableLis /// The type of the object. /// The source. /// A continuation of the original stream. - /// source. + /// source. public static IObservable> DisposeMany(this IObservable> source) where T : notnull { - if (source is null) - throw new ArgumentNullException(nameof(source)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new DisposeMany(source).Run(); } @@ -680,7 +582,7 @@ public static IObservable> DisposeMany(this IObservableThe source. /// The transform factory. /// An observable which emits the change set. - /// + /// /// source /// or /// valueSelector. @@ -689,15 +591,9 @@ public static IObservable> DistinctValues(th where TObject : notnull where TValue : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (valueSelector is null) - { - throw new ArgumentNullException(nameof(valueSelector)); - } + valueSelector.ThrowArgumentNullExceptionIfNull(nameof(valueSelector)); return new Distinct(source, valueSelector).Run(); } @@ -711,7 +607,12 @@ public static IObservable> DistinctValues(th /// The others. /// An observable which emits the change set. public static IObservable> Except(this IObservable> source, params IObservable>[] others) - where T : notnull => source.Combine(CombineOperator.Except, others); + where T : notnull + { + others.ThrowArgumentNullExceptionIfNull(nameof(others)); + + return source.Combine(CombineOperator.Except, others); + } /// /// Apply a logical Except operator between the collections. @@ -773,15 +674,9 @@ public static IObservable> ExpireAfter(this ISourceList sou public static IObservable> ExpireAfter(this ISourceList source, Func timeSelector, TimeSpan? pollingInterval = null, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (timeSelector is null) - { - throw new ArgumentNullException(nameof(timeSelector)); - } + timeSelector.ThrowArgumentNullExceptionIfNull(nameof(timeSelector)); var locker = new object(); var limiter = new ExpireAfter(source, timeSelector, pollingInterval, scheduler ?? Scheduler.Default, locker); @@ -796,19 +691,13 @@ public static IObservable> ExpireAfter(this ISourceList sou /// The source. /// The valueSelector. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> Filter(this IObservable> source, Func predicate) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } + predicate.ThrowArgumentNullExceptionIfNull(nameof(predicate)); return new Filter(source, predicate).Run(); } @@ -821,21 +710,15 @@ public static IObservable> Filter(this IObservableThe predicate which indicates which items should be included. /// Should the filter clear and replace, or calculate a diff-set. /// An observable which emits the change set. - /// source + /// source /// or /// filterController. public static IObservable> Filter(this IObservable> source, IObservable> predicate, ListFilterPolicy filterPolicy = ListFilterPolicy.CalculateDiff) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } + predicate.ThrowArgumentNullExceptionIfNull(nameof(predicate)); return new Filter(source, predicate, filterPolicy).Run(); } @@ -853,10 +736,7 @@ public static IObservable> Filter(this IObservable> FilterOnObservable(this IObservable> source, Func> objectFilterObservable, TimeSpan? propertyChangedThrottle = null, IScheduler? scheduler = null) where TObject : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new FilterOnObservable(source, objectFilterObservable, propertyChangedThrottle, scheduler).Run(); } @@ -877,20 +757,11 @@ public static IObservable> FilterOnObservable(this public static IObservable> FilterOnProperty(this IObservable> source, Expression> propertySelector, Func predicate, TimeSpan? propertyChangedThrottle = null, IScheduler? scheduler = null) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (propertySelector is null) - { - throw new ArgumentNullException(nameof(propertySelector)); - } + propertySelector.ThrowArgumentNullExceptionIfNull(nameof(propertySelector)); - if (predicate is null) - { - throw new ArgumentNullException(nameof(predicate)); - } + predicate.ThrowArgumentNullExceptionIfNull(nameof(predicate)); return new FilterOnProperty(source, propertySelector, predicate, propertyChangedThrottle, scheduler).Run(); } @@ -914,15 +785,9 @@ public static IObservable> FlattenBufferResult(this IObservable public static IObservable> ForEachChange(this IObservable> source, Action> action) where TObject : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + action.ThrowArgumentNullExceptionIfNull(nameof(action)); return source.Do(changes => changes.ForEach(action)); } @@ -938,15 +803,9 @@ public static IObservable> ForEachChange(this IObse public static IObservable> ForEachItemChange(this IObservable> source, Action> action) where TObject : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (action is null) - { - throw new ArgumentNullException(nameof(action)); - } + action.ThrowArgumentNullExceptionIfNull(nameof(action)); return source.Do(changes => changes.Flatten().ForEach(action)); } @@ -961,7 +820,7 @@ public static IObservable> ForEachItemChange(this I /// Force the grouping function to recalculate the group value. /// For example if you have a time based grouping with values like `Last Minute', 'Last Hour', 'Today' etc regrouper is used to refresh these groupings. /// An observable which emits the change set. - /// + /// /// source /// or /// groupSelector. @@ -970,15 +829,9 @@ public static IObservable>> GroupOn(source, groupSelector, regrouper).Run(); } @@ -999,15 +852,9 @@ public static IObservable>> GroupOnProperty(source, propertySelector, propertyChangedThrottle, scheduler).Run(); } @@ -1028,15 +875,9 @@ public static IObservable>> GroupOnProperty(source, propertySelector, propertyChangedThrottle, scheduler).Run(); } @@ -1051,7 +892,7 @@ public static IObservable>> GroupOnPropertyForce the grouping function to recalculate the group value. /// For example if you have a time based grouping with values like `Last Minute', 'Last Hour', 'Today' etc regrouper is used to refresh these groupings. /// An observable which emits the change set. - /// + /// /// source /// or /// groupSelectorKey. @@ -1060,15 +901,9 @@ public static IObservable>> GroupOnProperty(source, groupSelectorKey, regrouper).Run(); } @@ -1087,10 +922,7 @@ public static IObservable>> GroupOnProperty> LimitSizeTo(this ISourceList source, int sizeLimit, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (sizeLimit <= 0) { @@ -1112,21 +944,15 @@ public static IObservable> LimitSizeTo(this ISourceList sou /// The source. /// The observable selector. /// An observable which emits the destination value. - /// source + /// source /// or /// observableSelector. public static IObservable MergeMany(this IObservable> source, Func> observableSelector) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (observableSelector is null) - { - throw new ArgumentNullException(nameof(observableSelector)); - } + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeMany(source, observableSelector).Run(); } @@ -1142,7 +968,12 @@ public static IObservable MergeMany(this IObserva /// Parameter was null. public static IObservable> MergeChangeSets(this IObservableList>> source, IComparer comparer) where TObject : notnull - where TKey : notnull => source.Connect().MergeChangeSets(comparer: comparer); + where TKey : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + + return source.Connect().MergeChangeSets(comparer: comparer); + } /// /// Merges all of the Cache Observable ChangeSets into a single ChangeSets while correctly handling multiple Keys and removal of the parent items. @@ -1156,7 +987,12 @@ public static IObservable> MergeChangeSetsParameter was null. public static IObservable> MergeChangeSets(this IObservableList>> source, IEqualityComparer? equalityComparer = null, IComparer? comparer = null) where TObject : notnull - where TKey : notnull => source.Connect().MergeChangeSets(equalityComparer, comparer); + where TKey : notnull + { + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + + return source.Connect().MergeChangeSets(equalityComparer, comparer); + } /// /// Merges all of the Cache Observable ChangeSets into a single ChangeSets while correctly handling multiple Keys and removal of the parent items. @@ -1171,7 +1007,7 @@ public static IObservable> MergeChangeSets> MergeChangeSets src, equalityComparer, comparer); } @@ -1208,8 +1044,15 @@ public static IObservable> MergeManyChangeSets(source, observableSelector).Run(); } @@ -1230,9 +1073,9 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); - if (comparer == null) throw new ArgumentNullException(nameof(comparer)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); return source.MergeManyChangeSets(observableSelector, equalityComparer: null, comparer: comparer); } @@ -1254,8 +1097,8 @@ public static IObservable> MergeManyCh where TDestination : notnull where TDestinationKey : notnull { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (observableSelector == null) throw new ArgumentNullException(nameof(observableSelector)); + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + observableSelector.ThrowArgumentNullExceptionIfNull(nameof(observableSelector)); return new MergeManyCacheChangeSets(source, observableSelector, equalityComparer, comparer).Run(); } @@ -1266,14 +1109,11 @@ public static IObservable> MergeManyCh /// The type of the item. /// The source. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> NotEmpty(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Where(s => s.Count != 0); } @@ -1288,15 +1128,8 @@ public static IObservable> NotEmpty(this IObservable> OnItemAdded(this IObservable> source, Action addAction) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (addAction is null) - { - throw new ArgumentNullException(nameof(addAction)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + addAction.ThrowArgumentNullExceptionIfNull(nameof(addAction)); return new OnBeingAdded(source, addAction).Run(); } @@ -1334,7 +1167,7 @@ public static IObservable> OnItemRefreshed(this IOb /// The remove action. /// Should the remove action be invoked when the subscription is disposed. /// An observable which emits the change set. - /// + /// /// source /// or /// removeAction. @@ -1342,15 +1175,8 @@ public static IObservable> OnItemRefreshed(this IOb public static IObservable> OnItemRemoved(this IObservable> source, Action removeAction, bool invokeOnUnsubscribe = true) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (removeAction is null) - { - throw new ArgumentNullException(nameof(removeAction)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + removeAction.ThrowArgumentNullExceptionIfNull(nameof(removeAction)); return new OnBeingRemoved(source, removeAction, invokeOnUnsubscribe).Run(); } @@ -1374,7 +1200,12 @@ public static IObservable> Or(this ICollectionThe others. /// An observable which emits the change set. public static IObservable> Or(this IObservable> source, params IObservable>[] others) - where T : notnull => source.Combine(CombineOperator.Or, others); + where T : notnull + { + others.ThrowArgumentNullExceptionIfNull(nameof(others)); + + return source.Combine(CombineOperator.Or, others); + } /// /// Dynamically apply a logical Or operator between the items in the outer observable list. @@ -1416,15 +1247,8 @@ public static IObservable> Or(this IObservableList> Page(this IObservable> source, IObservable requests) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (requests is null) - { - throw new ArgumentNullException(nameof(requests)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + requests.ThrowArgumentNullExceptionIfNull(nameof(requests)); return new Pager(source, requests).Run(); } @@ -1444,15 +1268,8 @@ public static IObservable> Page(this IObservable(this IObservable> source, ISourceList destination) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (destination is null) - { - throw new ArgumentNullException(nameof(destination)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + destination.ThrowArgumentNullExceptionIfNull(nameof(destination)); return source.Subscribe(changes => destination.Edit(updater => updater.Clone(changes))); } @@ -1465,7 +1282,7 @@ public static IDisposable PopulateInto(this IObservable> source /// The source. /// The result selector. /// An observable which emits the destination value. - /// + /// /// source /// or /// resultSelector. @@ -1473,15 +1290,8 @@ public static IDisposable PopulateInto(this IObservable> source public static IObservable QueryWhenChanged(this IObservable> source, Func, TDestination> resultSelector) where TObject : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (resultSelector is null) - { - throw new ArgumentNullException(nameof(resultSelector)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + resultSelector.ThrowArgumentNullExceptionIfNull(nameof(resultSelector)); return source.QueryWhenChanged().Select(resultSelector); } @@ -1492,14 +1302,11 @@ public static IObservable QueryWhenChanged( /// The type of the object. /// The source. /// An observable which emits the read only collection. - /// source. + /// source. public static IObservable> QueryWhenChanged(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new QueryWhenChanged(source).Run(); } @@ -1513,10 +1320,7 @@ public static IObservable> QueryWhenChanged(this IObse public static IObservable> RefCount(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new RefCount(source).Run(); } @@ -1531,10 +1335,7 @@ public static IObservable> RefCount(this IObservable> RemoveIndex(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select(changes => new ChangeSet(changes.YieldWithoutIndex())); } @@ -1545,7 +1346,7 @@ public static IObservable> RemoveIndex(this IObservableThe type of the item. /// The source. /// An observable which emits the change set. - /// + /// /// source /// or /// comparer. @@ -1554,10 +1355,7 @@ public static IObservable> Reverse(this IObservable(); - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.Select(changes => new ChangeSet(reverser.Reverse(changes))); } @@ -1568,14 +1366,11 @@ public static IObservable> Reverse(this IObservableThe type of the object. /// The source. /// An observable which emits the change set. - /// source. + /// source. public static IObservable> SkipInitial(this IObservable> source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.DeferUntilLoaded().Skip(1); } @@ -1591,21 +1386,14 @@ public static IObservable> SkipInitial(this IObservableAn observable comparer used to change the comparer on which the sorted list i. /// Since sorting can be slow for large record sets, the reset threshold is used to force the list re-ordered. /// An observable which emits the change set. - /// source + /// source /// or /// comparer. public static IObservable> Sort(this IObservable> source, IComparer comparer, SortOptions options = SortOptions.None, IObservable? resort = null, IObservable>? comparerChanged = null, int resetThreshold = 50) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (comparer is null) - { - throw new ArgumentNullException(nameof(comparer)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + comparer.ThrowArgumentNullExceptionIfNull(nameof(comparer)); return new Sort(source, comparer, options, resort, comparerChanged, resetThreshold).Run(); } @@ -1620,21 +1408,14 @@ public static IObservable> Sort(this IObservable> /// OnNext of this observable causes data to resort. This is required when the value which is sorted on mutable. /// Since sorting can be slow for large record sets, the reset threshold is used to force the list re-ordered. /// An observable which emits the change set. - /// source + /// source /// or /// comparer. public static IObservable> Sort(this IObservable> source, IObservable> comparerChanged, SortOptions options = SortOptions.None, IObservable? resort = null, int resetThreshold = 50) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (comparerChanged is null) - { - throw new ArgumentNullException(nameof(comparerChanged)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + comparerChanged.ThrowArgumentNullExceptionIfNull(nameof(comparerChanged)); return new Sort(source, null, options, resort, comparerChanged, resetThreshold).Run(); } @@ -1655,7 +1436,7 @@ public static IObservable> StartWithEmpty(this IObservableThe source. /// The subscription function. /// An observable which emits the change set. - /// source + /// source /// or /// subscriptionFactory. /// @@ -1664,15 +1445,8 @@ public static IObservable> StartWithEmpty(this IObservable> SubscribeMany(this IObservable> source, Func subscriptionFactory) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (subscriptionFactory is null) - { - throw new ArgumentNullException(nameof(subscriptionFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + subscriptionFactory.ThrowArgumentNullExceptionIfNull(nameof(subscriptionFactory)); return new SubscribeMany(source, subscriptionFactory).Run(); } @@ -1701,10 +1475,7 @@ public static IObservable> SuppressRefresh(this IObservable> Switch(this IObservable> sources) where T : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return sources.Select(cache => cache.Connect()).Switch(); } @@ -1724,10 +1495,7 @@ public static IObservable> Switch(this IObservable> Switch(this IObservable>> sources) where T : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return new Switch(sources).Run(); } @@ -1749,16 +1517,13 @@ public static IObservable> ToCollection(th /// The source. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable source, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return ToObservableChangeSet(source, null, -1, scheduler); } @@ -1772,21 +1537,14 @@ public static IObservable> ToObservableChangeSet(this IObservab /// Specify on a per object level the maximum time before an object expires from a cache. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable source, Func expireAfter, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (expireAfter is null) - { - throw new ArgumentNullException(nameof(expireAfter)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + expireAfter.ThrowArgumentNullExceptionIfNull(nameof(expireAfter)); return ToObservableChangeSet(source, expireAfter, -1, scheduler); } @@ -1800,16 +1558,13 @@ public static IObservable> ToObservableChangeSet(this IObservab /// Remove the oldest items when the size has reached this limit. Supply -1 to disable size limiting. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable source, int limitSizeTo, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return ToObservableChangeSet(source, null, limitSizeTo, scheduler); } @@ -1824,16 +1579,13 @@ public static IObservable> ToObservableChangeSet(this IObservab /// Remove the oldest items when the size has reached this limit. Supply -1 to disable size limiting. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable source, Func? expireAfter, int limitSizeTo, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new ToObservableChangeSet(source, expireAfter, limitSizeTo, scheduler).Run(); } @@ -1846,7 +1598,7 @@ public static IObservable> ToObservableChangeSet(this IObservab /// The source. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable> source, IScheduler? scheduler = null) @@ -1861,7 +1613,7 @@ public static IObservable> ToObservableChangeSet(this IObservab /// Remove the oldest items when the size has reached this limit. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable> source, int limitSizeTo, IScheduler? scheduler = null) @@ -1876,7 +1628,7 @@ public static IObservable> ToObservableChangeSet(this IObservab /// Specify on a per object level the maximum time before an object expires from a cache. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable> source, Func expireAfter, IScheduler? scheduler = null) @@ -1892,16 +1644,13 @@ public static IObservable> ToObservableChangeSet(this IObservab /// Remove the oldest items when the size has reached this limit. /// The scheduler (only used for time expiry). /// An observable which emits a change set. - /// source + /// source /// or /// keySelector. public static IObservable> ToObservableChangeSet(this IObservable> source, Func? expireAfter, int limitSizeTo, IScheduler? scheduler = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new ToObservableChangeSet(source, expireAfter, limitSizeTo, scheduler).Run(); } @@ -1916,10 +1665,7 @@ public static IObservable> ToObservableChangeSet(this IObservab public static IObservable> Top(this IObservable> source, int numberOfItems) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); if (numberOfItems <= 0) { @@ -1966,7 +1712,7 @@ public static IObservable> ToSortedCollectionThe transform factory. /// Should a new transform be applied when a refresh event is received. /// An observable which emits the change set. - /// + /// /// source /// or /// valueSelector. @@ -1975,15 +1721,9 @@ public static IObservable> Transform((t, _, _) => transformFactory(t), transformOnRefresh); } @@ -1997,7 +1737,7 @@ public static IObservable> TransformThe transform function. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. @@ -2006,15 +1746,8 @@ public static IObservable> Transform((t, _, idx) => transformFactory(t, idx), transformOnRefresh); } @@ -2029,7 +1762,7 @@ public static IObservable> TransformThe transform function. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. @@ -2038,15 +1771,8 @@ public static IObservable> Transform((t, previous, _) => transformFactory(t, previous), transformOnRefresh); } @@ -2061,7 +1787,7 @@ public static IObservable> TransformThe transform factory. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. @@ -2070,15 +1796,8 @@ public static IObservable> Transform(source, transformFactory, transformOnRefresh).Run(); } @@ -2092,26 +1811,21 @@ public static IObservable> TransformThe transform factory. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync( - this IObservable> source, Func> transformFactory, + this IObservable> source, + Func> transformFactory, bool transformOnRefresh = false) where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return source.TransformAsync((t, _, _) => transformFactory(t), transformOnRefresh); } @@ -2125,26 +1839,21 @@ public static IObservable> TransformAsyncThe transform factory. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync( - this IObservable> source, Func> transformFactory, + this IObservable> source, + Func> transformFactory, bool transformOnRefresh = false) where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return source.TransformAsync((t, _, i) => transformFactory(t, i), transformOnRefresh); } @@ -2158,26 +1867,21 @@ public static IObservable> TransformAsyncThe transform factory. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync( - this IObservable> source, Func, Task> transformFactory, + this IObservable> source, + Func, Task> transformFactory, bool transformOnRefresh = false) where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return source.TransformAsync((t, d, _) => transformFactory(t, d), transformOnRefresh); } @@ -2191,26 +1895,21 @@ public static IObservable> TransformAsyncThe transform factory. /// Should a new transform be applied when a refresh event is received. /// A an observable change set of the transformed object. - /// + /// /// source /// or /// valueSelector. /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Roslynator", "RCS1047:Non-asynchronous method name should not end with 'Async'.", Justification = "By Design.")] public static IObservable> TransformAsync( - this IObservable> source, Func, int, Task> transformFactory, + this IObservable> source, + Func, int, Task> transformFactory, bool transformOnRefresh = false) where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (transformFactory is null) - { - throw new ArgumentNullException(nameof(transformFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + transformFactory.ThrowArgumentNullExceptionIfNull(nameof(transformFactory)); return new TransformAsync(source, transformFactory, transformOnRefresh).Run(); } @@ -2224,7 +1923,7 @@ public static IObservable> TransformAsyncThe selector function which selects the enumerable. /// Used when an item has been replaced to determine whether child items are the same as previous children. /// An observable which emits the change set. - /// + /// /// source /// or /// manySelector. @@ -2233,15 +1932,8 @@ public static IObservable> TransformMany(source, manySelector, equalityComparer).Run(); } @@ -2295,15 +1987,9 @@ public static IObservable> TransformMany> Virtualise(this IObservable> source, IObservable requests) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); - if (requests is null) - { - throw new ArgumentNullException(nameof(requests)); - } + requests.ThrowArgumentNullExceptionIfNull(nameof(requests)); return new Virtualiser(source, requests).Run(); } @@ -2318,10 +2004,7 @@ public static IObservable> Virtualise(this IObservable WhenAnyPropertyChanged(this IObservable> source, params string[] propertiesToMonitor) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return source.MergeMany(t => t.WhenAnyPropertyChanged(propertiesToMonitor)); } @@ -2338,15 +2021,8 @@ public static IObservable> Virtualise(this IObservable> WhenPropertyChanged(this IObservable> source, Expression> propertyAccessor, bool notifyOnInitialValue = true) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertyAccessor is null) - { - throw new ArgumentNullException(nameof(propertyAccessor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertyAccessor.ThrowArgumentNullExceptionIfNull(nameof(propertyAccessor)); var factory = propertyAccessor.GetFactory(); return source.MergeMany(t => factory(t, notifyOnInitialValue)); @@ -2364,15 +2040,8 @@ public static IObservable> WhenPropertyChanged WhenValueChanged(this IObservable> source, Expression> propertyAccessor, bool notifyOnInitialValue = true) where TObject : INotifyPropertyChanged { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (propertyAccessor is null) - { - throw new ArgumentNullException(nameof(propertyAccessor)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + propertyAccessor.ThrowArgumentNullExceptionIfNull(nameof(propertyAccessor)); var factory = propertyAccessor.GetFactory(); return source.MergeMany(t => factory(t, notifyOnInitialValue).Select(pv => pv.Value)); @@ -2385,14 +2054,11 @@ public static IObservable> WhenPropertyChangedThe source. /// The reasons. /// An observable which emits the change set. - /// Must enter at least 1 reason. + /// Must enter at least 1 reason. public static IObservable> WhereReasonsAre(this IObservable> source, params ListChangeReason[] reasons) where T : notnull { - if (reasons is null) - { - throw new ArgumentNullException(nameof(reasons)); - } + reasons.ThrowArgumentNullExceptionIfNull(nameof(reasons)); if (reasons.Length == 0) { @@ -2415,14 +2081,11 @@ public static IObservable> WhereReasonsAre(this IObservableThe source. /// The reasons. /// An observable which emits the change set. - /// Must enter at least 1 reason. + /// Must enter at least 1 reason. public static IObservable> WhereReasonsAreNot(this IObservable> source, params ListChangeReason[] reasons) where T : notnull { - if (reasons is null) - { - throw new ArgumentNullException(nameof(reasons)); - } + reasons.ThrowArgumentNullExceptionIfNull(nameof(reasons)); if (reasons.Length == 0) { @@ -2457,7 +2120,12 @@ public static IObservable> WhereReasonsAreNot(this IObservable< /// The others. /// An observable which emits the change set. public static IObservable> Xor(this IObservable> source, params IObservable>[] others) - where T : notnull => source.Combine(CombineOperator.Xor, others); + where T : notnull + { + others.ThrowArgumentNullExceptionIfNull(nameof(others)); + + return source.Combine(CombineOperator.Xor, others); + } /// /// Apply a logical Xor operator between the collections. @@ -2502,10 +2170,7 @@ public static IObservable> Xor(this IObservableList> Combine(this ICollection>> sources, CombineOperator type) where T : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return new Combiner(sources, type).Run(); } @@ -2513,15 +2178,8 @@ private static IObservable> Combine(this ICollection> Combine(this IObservable> source, CombineOperator type, params IObservable>[] others) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (others is null) - { - throw new ArgumentNullException(nameof(others)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + others.ThrowArgumentNullExceptionIfNull(nameof(others)); if (others.Length == 0) { @@ -2535,10 +2193,7 @@ private static IObservable> Combine(this IObservable> Combine(this IObservableList> sources, CombineOperator type) where T : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return Observable.Create>( observer => @@ -2552,10 +2207,7 @@ private static IObservable> Combine(this IObservableList> Combine(this IObservableList> sources, CombineOperator type) where T : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return Observable.Create>( observer => @@ -2569,10 +2221,7 @@ private static IObservable> Combine(this IObservableList> Combine(this IObservableList>> sources, CombineOperator type) where T : notnull { - if (sources is null) - { - throw new ArgumentNullException(nameof(sources)); - } + sources.ThrowArgumentNullExceptionIfNull(nameof(sources)); return new DynamicCombiner(sources, type).Run(); } diff --git a/src/DynamicData/List/SortOptions.cs b/src/DynamicData/List/SortOptions.cs index 87919af20..73a546e37 100644 --- a/src/DynamicData/List/SortOptions.cs +++ b/src/DynamicData/List/SortOptions.cs @@ -9,7 +9,6 @@ namespace DynamicData; /// /// Options for sorting. /// -[SuppressMessage("Design", "CA1717: Only flags should have plural names", Justification = "Backwards compatibility")] public enum SortOptions { /// diff --git a/src/DynamicData/List/SourceList.cs b/src/DynamicData/List/SourceList.cs index 7494601f6..fd4d27322 100644 --- a/src/DynamicData/List/SourceList.cs +++ b/src/DynamicData/List/SourceList.cs @@ -113,10 +113,7 @@ public void Dispose() /// public void Edit(Action> updateAction) { - if (updateAction is null) - { - throw new ArgumentNullException(nameof(updateAction)); - } + updateAction.ThrowArgumentNullExceptionIfNull(nameof(updateAction)); lock (_locker) { diff --git a/src/DynamicData/List/SourceListEditConvenienceEx.cs b/src/DynamicData/List/SourceListEditConvenienceEx.cs index 1784431da..f266af37e 100644 --- a/src/DynamicData/List/SourceListEditConvenienceEx.cs +++ b/src/DynamicData/List/SourceListEditConvenienceEx.cs @@ -21,10 +21,7 @@ public static class SourceListEditConvenienceEx public static void Add(this ISourceList source, T item) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.Add(item)); } @@ -38,10 +35,7 @@ public static void Add(this ISourceList source, T item) public static void AddRange(this ISourceList source, IEnumerable items) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.AddRange(items)); } @@ -54,10 +48,7 @@ public static void AddRange(this ISourceList source, IEnumerable items) public static void Clear(this ISourceList source) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.Clear()); } @@ -73,15 +64,8 @@ public static void Clear(this ISourceList source) public static void EditDiff(this ISourceList source, IEnumerable allItems, IEqualityComparer? equalityComparer = null) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (allItems is null) - { - throw new ArgumentNullException(nameof(allItems)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + allItems.ThrowArgumentNullExceptionIfNull(nameof(allItems)); var editDiff = new EditDiff(source, equalityComparer); editDiff.Edit(allItems); @@ -97,10 +81,7 @@ public static void EditDiff(this ISourceList source, IEnumerable allIte public static void Insert(this ISourceList source, int index, T item) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.Insert(index, item)); } @@ -115,10 +96,7 @@ public static void Insert(this ISourceList source, int index, T item) public static void InsertRange(this ISourceList source, IEnumerable items, int index) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.AddRange(items, index)); } @@ -133,10 +111,7 @@ public static void InsertRange(this ISourceList source, IEnumerable ite public static void Move(this ISourceList source, int original, int destination) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.Move(original, destination)); } @@ -151,11 +126,8 @@ public static void Move(this ISourceList source, int original, int destina public static bool Remove(this ISourceList source, T item) where T : notnull { - bool removed = false; - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + var removed = false; + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => removed = list.Remove(item)); return removed; @@ -170,10 +142,7 @@ public static bool Remove(this ISourceList source, T item) public static void RemoveAt(this ISourceList source, int index) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.RemoveAt(index)); } @@ -187,10 +156,7 @@ public static void RemoveAt(this ISourceList source, int index) public static void RemoveMany(this ISourceList source, IEnumerable itemsToRemove) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.RemoveMany(itemsToRemove)); } @@ -207,10 +173,7 @@ public static void RemoveMany(this ISourceList source, IEnumerable item public static void RemoveRange(this ISourceList source, int index, int count) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.RemoveRange(index, count)); } @@ -225,10 +188,7 @@ public static void RemoveRange(this ISourceList source, int index, int cou public static void Replace(this ISourceList source, T original, T destination) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list.Replace(original, destination)); } @@ -243,10 +203,7 @@ public static void Replace(this ISourceList source, T original, T destinat public static void ReplaceAt(this ISourceList source, int index, T item) where T : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); source.Edit(list => list[index] = item); } diff --git a/src/DynamicData/List/SourceListEx.cs b/src/DynamicData/List/SourceListEx.cs index 0df4babd4..066261609 100644 --- a/src/DynamicData/List/SourceListEx.cs +++ b/src/DynamicData/List/SourceListEx.cs @@ -23,15 +23,8 @@ public static IObservable> Cast( where TSource : notnull where TDestination : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } - - if (conversionFactory is null) - { - throw new ArgumentNullException(nameof(conversionFactory)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); + conversionFactory.ThrowArgumentNullExceptionIfNull(nameof(conversionFactory)); return source.Connect().Cast(conversionFactory); } diff --git a/src/DynamicData/ObservableChangeSet.cs b/src/DynamicData/ObservableChangeSet.cs index ebe523165..a67a9c1e3 100644 --- a/src/DynamicData/ObservableChangeSet.cs +++ b/src/DynamicData/ObservableChangeSet.cs @@ -25,21 +25,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Create( cache => @@ -62,21 +49,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Observable.Create>( observer => @@ -109,21 +83,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Create(async (cache, _) => await subscribe(cache).ConfigureAwait(false), keySelector); } @@ -140,21 +101,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Observable.Create>( async (observer, ct) => @@ -188,21 +136,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Create((cache, _) => subscribe(cache), keySelector); } @@ -219,21 +154,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Observable.Create>( async (observer, ct) => @@ -276,21 +198,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Observable.Create>( async observer => @@ -323,21 +232,8 @@ public static IObservable> Create(Func< where TObject : notnull where TKey : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); - - ArgumentNullException.ThrowIfNull(keySelector); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } - - if (keySelector is null) - { - throw new ArgumentNullException(nameof(keySelector)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); + keySelector.ThrowArgumentNullExceptionIfNull(nameof(keySelector)); return Observable.Create>( async (observer, ct) => @@ -367,14 +263,7 @@ public static IObservable> Create(Func< public static IObservable> Create(Func, Action> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Create( list => @@ -393,14 +282,7 @@ public static IObservable> Create(Func, Action> public static IObservable> Create(Func, IDisposable> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Observable.Create>( observer => @@ -438,14 +320,7 @@ public static IObservable> Create(Func, IDisposa public static IObservable> Create(Func, Task> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Create((list, _) => subscribe(list)); } @@ -459,14 +334,7 @@ public static IObservable> Create(Func, Task> Create(Func, CancellationToken, Task> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Observable.Create>( async (observer, ct) => @@ -507,14 +375,7 @@ public static IObservable> Create(Func, Cancella public static IObservable> Create(Func, Task> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Create(async (list, _) => await subscribe(list).ConfigureAwait(false)); } @@ -528,14 +389,7 @@ public static IObservable> Create(Func, Task> Create(Func, CancellationToken, Task> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Observable.Create>( async (observer, ct) => @@ -575,14 +429,7 @@ public static IObservable> Create(Func, Cancella public static IObservable> Create(Func, Task> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Observable.Create>( async observer => @@ -612,14 +459,7 @@ public static IObservable> Create(Func, Task> su public static IObservable> Create(Func, CancellationToken, Task> subscribe) where T : notnull { -#if NET6_0_OR_GREATER - ArgumentNullException.ThrowIfNull(subscribe); -#else - if (subscribe is null) - { - throw new ArgumentNullException(nameof(subscribe)); - } -#endif + subscribe.ThrowArgumentNullExceptionIfNull(nameof(subscribe)); return Observable.Create>( async (observer, ct) => diff --git a/src/DynamicData/Platforms/net45/PFilter.cs b/src/DynamicData/Platforms/net45/PFilter.cs index 18b888d40..8a04b791d 100644 --- a/src/DynamicData/Platforms/net45/PFilter.cs +++ b/src/DynamicData/Platforms/net45/PFilter.cs @@ -11,42 +11,20 @@ // ReSharper disable once CheckNamespace namespace DynamicData.PLinq { - internal class PFilter + internal class PFilter(IObservable> source, Func filter, ParallelisationOptions parallelisationOptions) where TObject : notnull where TKey : notnull { - private readonly Func _filter; - - private readonly ParallelisationOptions _parallelisationOptions; - - private readonly IObservable> _source; - - public PFilter(IObservable> source, Func filter, ParallelisationOptions parallelisationOptions) - { - _source = source; - _filter = filter; - _parallelisationOptions = parallelisationOptions; - } - - public IObservable> Run() - { - return Observable.Create>( + public IObservable> Run() => Observable.Create>( observer => { - var filterer = new PLinqFilteredUpdater(_filter, _parallelisationOptions); - return _source.Select(filterer.Update).NotEmpty().SubscribeSafe(observer); + var filterer = new PLinqFilteredUpdater(filter, parallelisationOptions); + return source.Select(filterer.Update).NotEmpty().SubscribeSafe(observer); }); - } - private class PLinqFilteredUpdater : AbstractFilter + private sealed class PLinqFilteredUpdater(Func filter, ParallelisationOptions parallelisationOptions) : AbstractFilter(new ChangeAwareCache(), filter) { - private readonly ParallelisationOptions _parallelisationOptions; - - public PLinqFilteredUpdater(Func filter, ParallelisationOptions parallelisationOptions) - : base(new ChangeAwareCache(), filter) - { - _parallelisationOptions = parallelisationOptions; - } + private readonly ParallelisationOptions _parallelisationOptions = parallelisationOptions; protected override IEnumerable GetChangesWithFilter(ChangeSet updates) { diff --git a/src/DynamicData/Platforms/net45/PSubscribeMany.cs b/src/DynamicData/Platforms/net45/PSubscribeMany.cs index 6a018bd78..294cdce15 100644 --- a/src/DynamicData/Platforms/net45/PSubscribeMany.cs +++ b/src/DynamicData/Platforms/net45/PSubscribeMany.cs @@ -9,34 +9,22 @@ // ReSharper disable once CheckNamespace namespace DynamicData.PLinq { - internal class PSubscribeMany + internal class PSubscribeMany(IObservable> source, Func subscriptionFactory, ParallelisationOptions parallelisationOptions) where TObject : notnull where TKey : notnull { - private readonly ParallelisationOptions _parallelisationOptions; + private readonly IObservable> _source = source ?? throw new ArgumentNullException(nameof(source)); - private readonly IObservable> _source; + private readonly Func _subscriptionFactory = subscriptionFactory ?? throw new ArgumentNullException(nameof(subscriptionFactory)); - private readonly Func _subscriptionFactory; - - public PSubscribeMany(IObservable> source, Func subscriptionFactory, ParallelisationOptions parallelisationOptions) - { - _source = source ?? throw new ArgumentNullException(nameof(source)); - _subscriptionFactory = subscriptionFactory ?? throw new ArgumentNullException(nameof(subscriptionFactory)); - _parallelisationOptions = parallelisationOptions; - } - - public IObservable> Run() - { - return Observable.Create>( + public IObservable> Run() => Observable.Create>( observer => { var published = _source.Publish(); - var subscriptions = published.Transform((t, k) => _subscriptionFactory(t, k), _parallelisationOptions).DisposeMany().Subscribe(); + var subscriptions = published.Transform((t, k) => _subscriptionFactory(t, k), parallelisationOptions).DisposeMany().Subscribe(); return new CompositeDisposable(subscriptions, published.SubscribeSafe(observer), published.Connect()); }); - } } } diff --git a/src/DynamicData/Platforms/net45/PTransform.cs b/src/DynamicData/Platforms/net45/PTransform.cs index c155e80ff..1c5fe05cb 100644 --- a/src/DynamicData/Platforms/net45/PTransform.cs +++ b/src/DynamicData/Platforms/net45/PTransform.cs @@ -10,42 +10,28 @@ // ReSharper disable once CheckNamespace namespace DynamicData.PLinq { - internal sealed class PTransform + internal sealed class PTransform( + IObservable> source, + Func, TKey, TDestination> transformFactory, + ParallelisationOptions parallelisationOptions, + Action>? exceptionCallback = null) where TDestination : notnull where TSource : notnull where TKey : notnull { - private readonly IObservable> _source; - private readonly Func, TKey, TDestination> _transformFactory; - private readonly ParallelisationOptions _parallelisationOptions; - private readonly Action>? _exceptionCallback; - - public PTransform( - IObservable> source, - Func, TKey, TDestination> transformFactory, - ParallelisationOptions parallelisationOptions, - Action>? exceptionCallback = null) - { - _source = source; - _exceptionCallback = exceptionCallback; - _transformFactory = transformFactory; - _parallelisationOptions = parallelisationOptions; - } - - public IObservable> Run() - { - return Observable.Create>(observer => + public IObservable> Run() => + Observable.Create>(observer => { var cache = new ChangeAwareCache(); - var transformer = _source.Select(changes => DoTransform(cache, changes)); + var transformer = source.Select(changes => DoTransform(cache, changes)); return transformer.NotEmpty().SubscribeSafe(observer); }); - } - private IChangeSet DoTransform(ChangeAwareCache cache, IChangeSet changes) + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0305:Simplify collection initialization", Justification = "A collection initializer is not equivalent to a .ToArray() call for a ParallelQuery. This change actually introduces a race-condition exception.")] + private ChangeSet DoTransform(ChangeAwareCache cache, IChangeSet changes) { - var transformed = changes.ShouldParallelise(_parallelisationOptions) - ? changes.Parallelise(_parallelisationOptions).Select(ToDestination).ToArray() + var transformed = changes.ShouldParallelise(parallelisationOptions) + ? changes.Parallelise(parallelisationOptions).Select(ToDestination).ToArray() : changes.Select(ToDestination).ToArray(); return ProcessUpdates(cache, transformed); @@ -57,7 +43,7 @@ private TransformResult ToDestination(Change change) { if (change.Reason == ChangeReason.Add || change.Reason == ChangeReason.Update) { - var destination = _transformFactory(change.Current, change.Previous, change.Key); + var destination = transformFactory(change.Current, change.Previous, change.Key); return new TransformResult(change, destination); } @@ -66,7 +52,7 @@ private TransformResult ToDestination(Change change) catch (Exception ex) { // only handle errors if a handler has been specified - if (_exceptionCallback != null) + if (exceptionCallback != null) { return new TransformResult(change, ex); } @@ -75,7 +61,7 @@ private TransformResult ToDestination(Change change) } } - private IChangeSet ProcessUpdates(ChangeAwareCache cache, IEnumerable transformedItems) + private ChangeSet ProcessUpdates(ChangeAwareCache cache, IEnumerable transformedItems) { foreach (var result in transformedItems) { @@ -101,7 +87,7 @@ private IChangeSet ProcessUpdates(ChangeAwareCache(result.Error, result.Change.Current, result.Change.Key)); + exceptionCallback?.Invoke(new Error(result.Error, result.Change.Current, result.Change.Key)); } } @@ -110,7 +96,7 @@ private IChangeSet ProcessUpdates(ChangeAwareCache change, TDestination destination) + public TransformResult(in Change change, TDestination destination) : this() { Change = change; @@ -119,7 +105,7 @@ public TransformResult(Change change, TDestination destination) Key = change.Key; } - public TransformResult(Change change) + public TransformResult(in Change change) : this() { Change = change; @@ -128,7 +114,7 @@ public TransformResult(Change change) Key = change.Key; } - public TransformResult(Change change, Exception error) + public TransformResult(in Change change, Exception error) : this() { Change = change; diff --git a/src/DynamicData/Platforms/net45/ParallelOperators.cs b/src/DynamicData/Platforms/net45/ParallelOperators.cs index b33258f20..bc47c0ea6 100644 --- a/src/DynamicData/Platforms/net45/ParallelOperators.cs +++ b/src/DynamicData/Platforms/net45/ParallelOperators.cs @@ -22,15 +22,12 @@ public static class ParallelOperators /// The filter. /// The parallelisation options. /// An observable which emits a change set. - /// source. + /// source. public static IObservable> Filter(this IObservable> source, Func filter, ParallelisationOptions parallelisationOptions) where TObject : notnull where TKey : notnull { - if (source is null) - { - throw new ArgumentNullException(nameof(source)); - } + source.ThrowArgumentNullExceptionIfNull(nameof(source)); return new PFilter(source, filter, parallelisationOptions).Run(); } @@ -44,7 +41,7 @@ public static IObservable> Filter(this /// The subscription function. /// The parallelisation options. /// An observable which emits a change set. - /// source + /// source /// or /// subscriptionFactory. /// @@ -54,20 +51,9 @@ public static IObservable> SubscribeMany(source, (t, _) => subscriptionFactory(t), parallelisationOptions).Run(); } @@ -81,7 +67,7 @@ public static IObservable> SubscribeManyThe subscription function. /// The parallelisation options. /// An observable which emits a change set. - /// source + /// source /// or /// subscriptionFactory. /// @@ -91,20 +77,9 @@ public static IObservable> SubscribeMany(source, subscriptionFactory, parallelisationOptions).Run(); } @@ -121,7 +96,7 @@ public static IObservable> SubscribeMany /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, ParallelisationOptions parallelisationOptions) @@ -129,20 +104,9 @@ public static IObservable> Transform(source, (t, _, k) => transformFactory(t, k), parallelisationOptions).Run(); } @@ -159,16 +123,13 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> Transform(this IObservable> source, Func transformFactory, ParallelisationOptions parallelisationOptions) where TDestination : notnull where TSource : notnull - where TKey : notnull - { - return new PTransform(source, (t, _, _) => transformFactory(t), parallelisationOptions).Run(); - } + where TKey : notnull => new PTransform(source, (t, _, _) => transformFactory(t), parallelisationOptions).Run(); /// /// Projects each update item to a new form using the specified transform function, @@ -186,7 +147,7 @@ public static IObservable> Transform /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func transformFactory, Action> errorHandler, ParallelisationOptions parallelisationOptions) @@ -194,25 +155,10 @@ public static IObservable> TransformSafe(source, (t, _, _) => transformFactory(t), parallelisationOptions, errorHandler).Run(); } @@ -233,16 +179,13 @@ public static IObservable> TransformSafe /// A transformed update collection. /// - /// source + /// source /// or /// transformFactory. public static IObservable> TransformSafe(this IObservable> source, Func transformFactory, Action> errorHandler, ParallelisationOptions parallelisationOptions) where TDestination : notnull where TSource : notnull - where TKey : notnull - { - return new PTransform(source, (t, _, k) => transformFactory(t, k), parallelisationOptions, errorHandler).Run(); - } + where TKey : notnull => new PTransform(source, (t, _, k) => transformFactory(t, k), parallelisationOptions, errorHandler).Run(); } } diff --git a/src/DynamicData/Polyfills/CompilerFeatureRequiredAttribute.cs b/src/DynamicData/Polyfills/CompilerFeatureRequiredAttribute.cs index 876e92d99..e2ceceaea 100644 --- a/src/DynamicData/Polyfills/CompilerFeatureRequiredAttribute.cs +++ b/src/DynamicData/Polyfills/CompilerFeatureRequiredAttribute.cs @@ -6,19 +6,16 @@ namespace System.Runtime.CompilerServices; // Allows use of the C#11 `required` keyword, internally within this library, when targeting frameworks older than .NET 7. [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] -internal sealed class CompilerFeatureRequiredAttribute - : Attribute +internal sealed class CompilerFeatureRequiredAttribute(string featureName) + : Attribute { - public CompilerFeatureRequiredAttribute(string featureName) - => FeatureName = featureName; - - public string FeatureName { get; } - - public bool IsOptional { get; init; } - public const string RefStructs = nameof(RefStructs); public const string RequiredMembers = nameof(RequiredMembers); + + public string FeatureName { get; } = featureName; + + public bool IsOptional { get; init; } }