From 08ff3fe10bfa49749e2fc1d290958c98fae6a236 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 22 Oct 2025 12:11:29 -0600 Subject: [PATCH 1/4] Add .NET 8-10 targets --- Directory.Build.props | 6 ------ F23.StringSimilarity.sln | 2 +- .../F23.StringSimilarity.Benchmarks/Benchmarks.cs | 0 .../F23.StringSimilarity.Benchmarks.csproj | 4 ++-- .../F23.StringSimilarity.Benchmarks/Program.cs | 0 src/Directory.Build.props | 4 ---- .../F23.StringSimilarity.csproj | 13 ++++++++++--- src/F23.StringSimilarity/Properties/AssemblyInfo.cs | 4 ++++ test/Directory.Build.props | 4 ---- .../F23.StringSimilarity.Tests.csproj | 5 +++++ 10 files changed, 22 insertions(+), 20 deletions(-) delete mode 100644 Directory.Build.props rename {test => benchmarks}/F23.StringSimilarity.Benchmarks/Benchmarks.cs (100%) rename {test => benchmarks}/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj (77%) rename {test => benchmarks}/F23.StringSimilarity.Benchmarks/Program.cs (100%) delete mode 100644 src/Directory.Build.props delete mode 100644 test/Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props deleted file mode 100644 index 232afa3..0000000 --- a/Directory.Build.props +++ /dev/null @@ -1,6 +0,0 @@ - - - $(SolutionDir)StringSimilarity.NET.snk - true - - diff --git a/F23.StringSimilarity.sln b/F23.StringSimilarity.sln index 148038f..612f1a1 100644 --- a/F23.StringSimilarity.sln +++ b/F23.StringSimilarity.sln @@ -7,7 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity", "src EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity.Tests", "test\F23.StringSimilarity.Tests\F23.StringSimilarity.Tests.csproj", "{68F339E6-278F-4B04-A6ED-422AAD30591F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity.Benchmarks", "test\F23.StringSimilarity.Benchmarks\F23.StringSimilarity.Benchmarks.csproj", "{3A9605B1-820C-43C2-8F9B-72BCA5F5543B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity.Benchmarks", "benchmarks\F23.StringSimilarity.Benchmarks\F23.StringSimilarity.Benchmarks.csproj", "{3A9605B1-820C-43C2-8F9B-72BCA5F5543B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/test/F23.StringSimilarity.Benchmarks/Benchmarks.cs b/benchmarks/F23.StringSimilarity.Benchmarks/Benchmarks.cs similarity index 100% rename from test/F23.StringSimilarity.Benchmarks/Benchmarks.cs rename to benchmarks/F23.StringSimilarity.Benchmarks/Benchmarks.cs diff --git a/test/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj b/benchmarks/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj similarity index 77% rename from test/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj rename to benchmarks/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj index 8035ce4..c838a74 100644 --- a/test/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj +++ b/benchmarks/F23.StringSimilarity.Benchmarks/F23.StringSimilarity.Benchmarks.csproj @@ -2,14 +2,14 @@ Exe - net8.0 + net10.0 enable enable false - + diff --git a/test/F23.StringSimilarity.Benchmarks/Program.cs b/benchmarks/F23.StringSimilarity.Benchmarks/Program.cs similarity index 100% rename from test/F23.StringSimilarity.Benchmarks/Program.cs rename to benchmarks/F23.StringSimilarity.Benchmarks/Program.cs diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index 3ff68bc..0000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/F23.StringSimilarity/F23.StringSimilarity.csproj b/src/F23.StringSimilarity/F23.StringSimilarity.csproj index cc7b1f3..649938b 100644 --- a/src/F23.StringSimilarity/F23.StringSimilarity.csproj +++ b/src/F23.StringSimilarity/F23.StringSimilarity.csproj @@ -1,6 +1,6 @@ - netstandard2.0 + netstandard2.0;net8.0;net9.0;net10.0 F23.StringSimilarity string;similarity;distance;levenshtein;jaro-winkler;lcs;cosine StringSimilarity.NET @@ -16,10 +16,17 @@ true true snupkg - 7.0.0 + 8.0.0-alpha + + + FEATURE_SIGNED_ASSEMBLY;$(DefineConstants) + $(SolutionDir)StringSimilarity.NET.snk + true - + + + diff --git a/src/F23.StringSimilarity/Properties/AssemblyInfo.cs b/src/F23.StringSimilarity/Properties/AssemblyInfo.cs index be0fd35..d21ce89 100644 --- a/src/F23.StringSimilarity/Properties/AssemblyInfo.cs +++ b/src/F23.StringSimilarity/Properties/AssemblyInfo.cs @@ -1,3 +1,7 @@ using System.Runtime.CompilerServices; +#if FEATURE_SIGNED_ASSEMBLY [assembly: InternalsVisibleTo("F23.StringSimilarity.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b9a3cf7cbdb26a91b8a50d70ec052fe9f1edd3d1989e1079d0b0c1930e2030273a82629e18c7f2932a1e7957d48ec36b2703cda7bab46f3a0684cc86637e02dac24c857a43ef9a63a6459b147d11ec43b75b181de0aa326931ae13ba31c06977b309424c730d895144feab54da5ad84a604f90b2d672406177782027c8413caa")] +#else +[assembly: InternalsVisibleTo("F23.StringSimilarity.Tests")] +#endif diff --git a/test/Directory.Build.props b/test/Directory.Build.props deleted file mode 100644 index 3ff68bc..0000000 --- a/test/Directory.Build.props +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/test/F23.StringSimilarity.Tests/F23.StringSimilarity.Tests.csproj b/test/F23.StringSimilarity.Tests/F23.StringSimilarity.Tests.csproj index bc23f6a..8d91a36 100644 --- a/test/F23.StringSimilarity.Tests/F23.StringSimilarity.Tests.csproj +++ b/test/F23.StringSimilarity.Tests/F23.StringSimilarity.Tests.csproj @@ -7,6 +7,11 @@ enable + + $(SolutionDir)StringSimilarity.NET.snk + true + + From 7d84fef38c64672a876c0f4d223890988776abb3 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 22 Oct 2025 12:14:54 -0600 Subject: [PATCH 2/4] Migrate to slnx solution format --- F23.StringSimilarity.sln | 34 ---------------------------------- F23.StringSimilarity.slnx | 5 +++++ 2 files changed, 5 insertions(+), 34 deletions(-) delete mode 100644 F23.StringSimilarity.sln create mode 100644 F23.StringSimilarity.slnx diff --git a/F23.StringSimilarity.sln b/F23.StringSimilarity.sln deleted file mode 100644 index 612f1a1..0000000 --- a/F23.StringSimilarity.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity", "src\F23.StringSimilarity\F23.StringSimilarity.csproj", "{FA27327B-BCCC-46C7-8EED-BBD1ECF4BF53}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity.Tests", "test\F23.StringSimilarity.Tests\F23.StringSimilarity.Tests.csproj", "{68F339E6-278F-4B04-A6ED-422AAD30591F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "F23.StringSimilarity.Benchmarks", "benchmarks\F23.StringSimilarity.Benchmarks\F23.StringSimilarity.Benchmarks.csproj", "{3A9605B1-820C-43C2-8F9B-72BCA5F5543B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FA27327B-BCCC-46C7-8EED-BBD1ECF4BF53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA27327B-BCCC-46C7-8EED-BBD1ECF4BF53}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA27327B-BCCC-46C7-8EED-BBD1ECF4BF53}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA27327B-BCCC-46C7-8EED-BBD1ECF4BF53}.Release|Any CPU.Build.0 = Release|Any CPU - {68F339E6-278F-4B04-A6ED-422AAD30591F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {68F339E6-278F-4B04-A6ED-422AAD30591F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {68F339E6-278F-4B04-A6ED-422AAD30591F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {68F339E6-278F-4B04-A6ED-422AAD30591F}.Release|Any CPU.Build.0 = Release|Any CPU - {3A9605B1-820C-43C2-8F9B-72BCA5F5543B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3A9605B1-820C-43C2-8F9B-72BCA5F5543B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3A9605B1-820C-43C2-8F9B-72BCA5F5543B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3A9605B1-820C-43C2-8F9B-72BCA5F5543B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/F23.StringSimilarity.slnx b/F23.StringSimilarity.slnx new file mode 100644 index 0000000..52b49bc --- /dev/null +++ b/F23.StringSimilarity.slnx @@ -0,0 +1,5 @@ + + + + + From 5300e81c331d621d0954ed5e0a7a3a8b54402c54 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 22 Oct 2025 14:45:24 -0600 Subject: [PATCH 3/4] Remove redundant checks that cause warnings in modern .NET --- src/F23.StringSimilarity/Damerau.cs | 12 +--------- .../F23.StringSimilarity.csproj | 1 + src/F23.StringSimilarity/JaroWinkler.cs | 20 ++++------------ src/F23.StringSimilarity/Levenshtein.cs | 14 ++--------- .../LongestCommonSubsequence.cs | 24 ++----------------- src/F23.StringSimilarity/MetricLCS.cs | 12 +--------- .../NormalizedLevenshtein.cs | 14 ++--------- .../OptimalStringAlignment.cs | 12 +--------- 8 files changed, 15 insertions(+), 94 deletions(-) diff --git a/src/F23.StringSimilarity/Damerau.cs b/src/F23.StringSimilarity/Damerau.cs index dd6138e..7268910 100644 --- a/src/F23.StringSimilarity/Damerau.cs +++ b/src/F23.StringSimilarity/Damerau.cs @@ -31,7 +31,7 @@ namespace F23.StringSimilarity { /// - /// Implementation of Damerau-Levenshtein distance with transposition (also + /// Implementation of Damerau-Levenshtein distance with transposition (also /// sometimes calls unrestricted Damerau-Levenshtein distance). /// It is the minimum number of operations needed to transform one string into /// the other, where an operation is defined as an insertion, deletion, or @@ -59,16 +59,6 @@ public double Distance(string s1, string s2) public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 0; diff --git a/src/F23.StringSimilarity/F23.StringSimilarity.csproj b/src/F23.StringSimilarity/F23.StringSimilarity.csproj index 649938b..1b59d53 100644 --- a/src/F23.StringSimilarity/F23.StringSimilarity.csproj +++ b/src/F23.StringSimilarity/F23.StringSimilarity.csproj @@ -17,6 +17,7 @@ true snupkg 8.0.0-alpha + 14 FEATURE_SIGNED_ASSEMBLY;$(DefineConstants) diff --git a/src/F23.StringSimilarity/JaroWinkler.cs b/src/F23.StringSimilarity/JaroWinkler.cs index 88ad93a..3b0db96 100644 --- a/src/F23.StringSimilarity/JaroWinkler.cs +++ b/src/F23.StringSimilarity/JaroWinkler.cs @@ -49,7 +49,7 @@ public class JaroWinkler : INormalizedStringSimilarity, INormalizedStringDistanc /// The current value of the threshold used for adding the Winkler bonus. The default value is 0.7. /// private double Threshold { get; } - + /// /// Creates a new instance with default threshold (0.7) /// @@ -57,7 +57,7 @@ public JaroWinkler() { Threshold = DEFAULT_THRESHOLD; } - + /// /// Creates a new instance with given threshold to determine when Winkler bonus should /// be used. Set threshold to a negative value to get the Jaro distance. @@ -77,20 +77,10 @@ public JaroWinkler(double threshold) /// If s1 or s2 is null. public double Similarity(string s1, string s2) => Similarity(s1.AsSpan(), s2.AsSpan()); - + public double Similarity(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 1f; @@ -122,7 +112,7 @@ public double Similarity(ReadOnlySpan s1, ReadOnlySpan s2) /// If s1 or s2 is null. public double Distance(string s1, string s2) => 1.0 - Similarity(s1, s2); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable => 1.0 - Similarity(s1, s2); @@ -202,7 +192,7 @@ private static int[] Matches(ReadOnlySpan s1, ReadOnlySpan s2) break; } } - return new[] { matches, transpositions / 2, prefix, max.Length }; + return [matches, transpositions / 2, prefix, max.Length]; } } } diff --git a/src/F23.StringSimilarity/Levenshtein.cs b/src/F23.StringSimilarity/Levenshtein.cs index 0ccf97d..96be482 100644 --- a/src/F23.StringSimilarity/Levenshtein.cs +++ b/src/F23.StringSimilarity/Levenshtein.cs @@ -73,24 +73,14 @@ public class Levenshtein : IMetricStringDistance, IMetricSpanDistance /// If s1 or s2 is null. public double Distance(string s1, string s2, int limit) => Distance(s1.AsSpan(), s2.AsSpan(), limit); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable => Distance(s1, s2, int.MaxValue); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2, int limit) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 0; diff --git a/src/F23.StringSimilarity/LongestCommonSubsequence.cs b/src/F23.StringSimilarity/LongestCommonSubsequence.cs index ce5d4d0..bc10400 100644 --- a/src/F23.StringSimilarity/LongestCommonSubsequence.cs +++ b/src/F23.StringSimilarity/LongestCommonSubsequence.cs @@ -59,20 +59,10 @@ public class LongestCommonSubsequence : IStringDistance, ISpanDistance /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 0; @@ -91,20 +81,10 @@ public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) /// If s1 or s2 is null. public int Length(string s1, string s2) => Length(s1.AsSpan(), s2.AsSpan()); - + internal static int Length(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - /* function LCSLength(X[1..m], Y[1..n]) C = array(0..m, 0..n) for i := 0..m diff --git a/src/F23.StringSimilarity/MetricLCS.cs b/src/F23.StringSimilarity/MetricLCS.cs index 1d33ae6..fae7fba 100644 --- a/src/F23.StringSimilarity/MetricLCS.cs +++ b/src/F23.StringSimilarity/MetricLCS.cs @@ -43,20 +43,10 @@ public class MetricLCS : IMetricStringDistance, INormalizedStringDistance, IMetr /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 0; diff --git a/src/F23.StringSimilarity/NormalizedLevenshtein.cs b/src/F23.StringSimilarity/NormalizedLevenshtein.cs index 208e451..4443855 100644 --- a/src/F23.StringSimilarity/NormalizedLevenshtein.cs +++ b/src/F23.StringSimilarity/NormalizedLevenshtein.cs @@ -44,20 +44,10 @@ public class NormalizedLevenshtein : INormalizedStringDistance, INormalizedStrin /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 0.0; @@ -82,7 +72,7 @@ public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) /// If s1 or s2 is null. public double Similarity(string s1, string s2) => 1.0 - Distance(s1, s2); - + public double Similarity(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable => 1.0 - Distance(s1, s2); diff --git a/src/F23.StringSimilarity/OptimalStringAlignment.cs b/src/F23.StringSimilarity/OptimalStringAlignment.cs index 13af7a1..6df5d43 100644 --- a/src/F23.StringSimilarity/OptimalStringAlignment.cs +++ b/src/F23.StringSimilarity/OptimalStringAlignment.cs @@ -43,20 +43,10 @@ public sealed class OptimalStringAlignment : IStringDistance, ISpanDistance /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { - if (s1 == null) - { - throw new ArgumentNullException(nameof(s1)); - } - - if (s2 == null) - { - throw new ArgumentNullException(nameof(s2)); - } - if (s1.SequenceEqual(s2)) { return 0; From b532e660e7e014762d0ae431263eba0a00b3e0d8 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Wed, 22 Oct 2025 14:49:49 -0600 Subject: [PATCH 4/4] Revert "Remove redundant checks that cause warnings in modern .NET" This reverts commit 5300e81c331d621d0954ed5e0a7a3a8b54402c54. --- src/F23.StringSimilarity/Damerau.cs | 12 +++++++++- .../F23.StringSimilarity.csproj | 1 - src/F23.StringSimilarity/JaroWinkler.cs | 20 ++++++++++++---- src/F23.StringSimilarity/Levenshtein.cs | 14 +++++++++-- .../LongestCommonSubsequence.cs | 24 +++++++++++++++++-- src/F23.StringSimilarity/MetricLCS.cs | 12 +++++++++- .../NormalizedLevenshtein.cs | 14 +++++++++-- .../OptimalStringAlignment.cs | 12 +++++++++- 8 files changed, 94 insertions(+), 15 deletions(-) diff --git a/src/F23.StringSimilarity/Damerau.cs b/src/F23.StringSimilarity/Damerau.cs index 7268910..dd6138e 100644 --- a/src/F23.StringSimilarity/Damerau.cs +++ b/src/F23.StringSimilarity/Damerau.cs @@ -31,7 +31,7 @@ namespace F23.StringSimilarity { /// - /// Implementation of Damerau-Levenshtein distance with transposition (also + /// Implementation of Damerau-Levenshtein distance with transposition (also /// sometimes calls unrestricted Damerau-Levenshtein distance). /// It is the minimum number of operations needed to transform one string into /// the other, where an operation is defined as an insertion, deletion, or @@ -59,6 +59,16 @@ public double Distance(string s1, string s2) public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 0; diff --git a/src/F23.StringSimilarity/F23.StringSimilarity.csproj b/src/F23.StringSimilarity/F23.StringSimilarity.csproj index 1b59d53..649938b 100644 --- a/src/F23.StringSimilarity/F23.StringSimilarity.csproj +++ b/src/F23.StringSimilarity/F23.StringSimilarity.csproj @@ -17,7 +17,6 @@ true snupkg 8.0.0-alpha - 14 FEATURE_SIGNED_ASSEMBLY;$(DefineConstants) diff --git a/src/F23.StringSimilarity/JaroWinkler.cs b/src/F23.StringSimilarity/JaroWinkler.cs index 3b0db96..88ad93a 100644 --- a/src/F23.StringSimilarity/JaroWinkler.cs +++ b/src/F23.StringSimilarity/JaroWinkler.cs @@ -49,7 +49,7 @@ public class JaroWinkler : INormalizedStringSimilarity, INormalizedStringDistanc /// The current value of the threshold used for adding the Winkler bonus. The default value is 0.7. /// private double Threshold { get; } - + /// /// Creates a new instance with default threshold (0.7) /// @@ -57,7 +57,7 @@ public JaroWinkler() { Threshold = DEFAULT_THRESHOLD; } - + /// /// Creates a new instance with given threshold to determine when Winkler bonus should /// be used. Set threshold to a negative value to get the Jaro distance. @@ -77,10 +77,20 @@ public JaroWinkler(double threshold) /// If s1 or s2 is null. public double Similarity(string s1, string s2) => Similarity(s1.AsSpan(), s2.AsSpan()); - + public double Similarity(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 1f; @@ -112,7 +122,7 @@ public double Similarity(ReadOnlySpan s1, ReadOnlySpan s2) /// If s1 or s2 is null. public double Distance(string s1, string s2) => 1.0 - Similarity(s1, s2); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable => 1.0 - Similarity(s1, s2); @@ -192,7 +202,7 @@ private static int[] Matches(ReadOnlySpan s1, ReadOnlySpan s2) break; } } - return [matches, transpositions / 2, prefix, max.Length]; + return new[] { matches, transpositions / 2, prefix, max.Length }; } } } diff --git a/src/F23.StringSimilarity/Levenshtein.cs b/src/F23.StringSimilarity/Levenshtein.cs index 96be482..0ccf97d 100644 --- a/src/F23.StringSimilarity/Levenshtein.cs +++ b/src/F23.StringSimilarity/Levenshtein.cs @@ -73,14 +73,24 @@ public class Levenshtein : IMetricStringDistance, IMetricSpanDistance /// If s1 or s2 is null. public double Distance(string s1, string s2, int limit) => Distance(s1.AsSpan(), s2.AsSpan(), limit); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable => Distance(s1, s2, int.MaxValue); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2, int limit) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 0; diff --git a/src/F23.StringSimilarity/LongestCommonSubsequence.cs b/src/F23.StringSimilarity/LongestCommonSubsequence.cs index bc10400..ce5d4d0 100644 --- a/src/F23.StringSimilarity/LongestCommonSubsequence.cs +++ b/src/F23.StringSimilarity/LongestCommonSubsequence.cs @@ -59,10 +59,20 @@ public class LongestCommonSubsequence : IStringDistance, ISpanDistance /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 0; @@ -81,10 +91,20 @@ public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) /// If s1 or s2 is null. public int Length(string s1, string s2) => Length(s1.AsSpan(), s2.AsSpan()); - + internal static int Length(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + /* function LCSLength(X[1..m], Y[1..n]) C = array(0..m, 0..n) for i := 0..m diff --git a/src/F23.StringSimilarity/MetricLCS.cs b/src/F23.StringSimilarity/MetricLCS.cs index fae7fba..1d33ae6 100644 --- a/src/F23.StringSimilarity/MetricLCS.cs +++ b/src/F23.StringSimilarity/MetricLCS.cs @@ -43,10 +43,20 @@ public class MetricLCS : IMetricStringDistance, INormalizedStringDistance, IMetr /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 0; diff --git a/src/F23.StringSimilarity/NormalizedLevenshtein.cs b/src/F23.StringSimilarity/NormalizedLevenshtein.cs index 4443855..208e451 100644 --- a/src/F23.StringSimilarity/NormalizedLevenshtein.cs +++ b/src/F23.StringSimilarity/NormalizedLevenshtein.cs @@ -44,10 +44,20 @@ public class NormalizedLevenshtein : INormalizedStringDistance, INormalizedStrin /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 0.0; @@ -72,7 +82,7 @@ public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) /// If s1 or s2 is null. public double Similarity(string s1, string s2) => 1.0 - Distance(s1, s2); - + public double Similarity(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable => 1.0 - Distance(s1, s2); diff --git a/src/F23.StringSimilarity/OptimalStringAlignment.cs b/src/F23.StringSimilarity/OptimalStringAlignment.cs index 6df5d43..13af7a1 100644 --- a/src/F23.StringSimilarity/OptimalStringAlignment.cs +++ b/src/F23.StringSimilarity/OptimalStringAlignment.cs @@ -43,10 +43,20 @@ public sealed class OptimalStringAlignment : IStringDistance, ISpanDistance /// If s1 or s2 is null. public double Distance(string s1, string s2) => Distance(s1.AsSpan(), s2.AsSpan()); - + public double Distance(ReadOnlySpan s1, ReadOnlySpan s2) where T : IEquatable { + if (s1 == null) + { + throw new ArgumentNullException(nameof(s1)); + } + + if (s2 == null) + { + throw new ArgumentNullException(nameof(s2)); + } + if (s1.SequenceEqual(s2)) { return 0;