| File: VersionRangeComparer.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Versioning\NuGet.Versioning.csproj (NuGet.Versioning) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using NuGet.Shared; namespace NuGet.Versioning { /// <summary> /// A version range comparer capable of using different VersionComparers to check if ranges are equivalent. /// </summary> public class VersionRangeComparer : IVersionRangeComparer { private readonly IVersionComparer _versionComparer; /// <summary> /// Default version range comparer. /// </summary> public VersionRangeComparer() : this(VersionComparer.Default) { } /// <summary> /// Compare versions with a specific VersionComparison /// </summary> public VersionRangeComparer(VersionComparison versionComparison) : this(VersionComparer.Get(versionComparison)) { } /// <summary> /// Compare versions with a specific IVersionComparer /// </summary> public VersionRangeComparer(IVersionComparer versionComparer) { if (versionComparer == null) { throw new ArgumentNullException(nameof(versionComparer)); } _versionComparer = versionComparer; } /// <summary> /// Default Version comparer /// </summary> public static IVersionRangeComparer Default { get; } = new VersionRangeComparer(VersionComparer.Default); internal static IVersionRangeComparer Version { get; } = new VersionRangeComparer(VersionComparer.Version); /// <summary> /// Compare versions using the Version and Release /// </summary> public static IVersionRangeComparer VersionRelease { get; } = new VersionRangeComparer(VersionComparer.VersionRelease); internal static IVersionRangeComparer VersionReleaseMetadata { get; } = new VersionRangeComparer(VersionComparer.VersionReleaseMetadata); /// <summary> /// Gets the appropriate version range comparer based on the specified version comparison. /// </summary> /// <param name="versionComparison">The version comparison to use.</param> /// <returns>An instance of <see cref="IVersionRangeComparer"/>.</returns> public static IVersionRangeComparer Get(VersionComparison versionComparison) { return versionComparison switch { VersionComparison.Default => Default, VersionComparison.Version => Version, VersionComparison.VersionRelease => VersionRelease, VersionComparison.VersionReleaseMetadata => VersionReleaseMetadata, _ => new VersionRangeComparer(versionComparison) }; } /// <summary> /// Checks if two version ranges are equivalent. This follows the rules of the version comparer /// when checking the bounds. /// </summary> public bool Equals(VersionRangeBase? x, VersionRangeBase? y) { if (ReferenceEquals(x, y)) { return true; } if (ReferenceEquals(y, null) || ReferenceEquals(x, null)) { return false; } return x.IsMinInclusive == y.IsMinInclusive && y.IsMaxInclusive == x.IsMaxInclusive #pragma warning disable CS8604 // Possible null reference argument. // BCL missing nullable annotations on IEqualityComparer<T> before .NET 5 && _versionComparer.Equals(y.MinVersion, x.MinVersion) && _versionComparer.Equals(y.MaxVersion, x.MaxVersion); #pragma warning restore CS8604 // Possible null reference argument. } /// <summary> /// Creates a hash code based on all properties of the range. This follows the rules of the /// version comparer when comparing the version bounds. /// </summary> public int GetHashCode(VersionRangeBase obj) { if (ReferenceEquals(obj, null)) { return 0; } var combiner = new HashCodeCombiner(); combiner.AddObject(obj.IsMinInclusive); combiner.AddObject(obj.IsMaxInclusive); if (obj.HasLowerBound) { combiner.AddObject(_versionComparer.GetHashCode(obj.MinVersion)); } if (obj.HasUpperBound) { combiner.AddObject(_versionComparer.GetHashCode(obj.MaxVersion)); } return combiner.CombinedHash; } } }