/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/Microsoft.PowerShell.Commands.Utility/commands/utility/ObjectCommandComparer.cs
235 строк
8 KB
xtqqczze
Fix IDE0083: UseNotPattern (#26209)
16 окт 2025, 08:24
Не верифицирован
16 окт 2025, 08:24
250144e
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #region Using directives using System; using System.Collections; using System.Globalization; using System.Management.Automation; #endregion namespace Microsoft.PowerShell.Commands { #region PSObject Comparer /// <summary> /// Keeps the property value of inputObject. Because the value of a non-existing property is null, /// isExistingProperty is needed to distinguish whether a property exists and its value is null or /// the property does not exist at all. /// </summary> internal sealed class ObjectCommandPropertyValue { private ObjectCommandPropertyValue() { } internal ObjectCommandPropertyValue(object propVal) { PropertyValue = propVal; IsExistingProperty = true; } /// <summary> /// Initializes a new instance of the <see cref="ObjectCommandPropertyValue"/> class. /// </summary> /// <param name="propVal">Property Value.</param> /// <param name="isCaseSensitive">Indicates if the Property value comparison has to be case sensitive or not.</param> /// <param name="cultureInfo">Culture Info of the Property Value.</param> internal ObjectCommandPropertyValue(object propVal, bool isCaseSensitive, CultureInfo cultureInfo) : this(propVal) { _caseSensitive = isCaseSensitive; this.cultureInfo = cultureInfo; } internal object PropertyValue { get; } internal bool IsExistingProperty { get; } /// <summary> /// Indicates if the Property Value comparison has to be Case sensitive or not. /// </summary> internal SwitchParameter CaseSensitive { get { return _caseSensitive; } } /// <summary> /// Gets the Culture Info of the Property Value. /// </summary> internal CultureInfo Culture { get { return cultureInfo; } } internal static readonly ObjectCommandPropertyValue NonExistingProperty = new(); internal static readonly ObjectCommandPropertyValue ExistingNullProperty = new(null); private readonly bool _caseSensitive; internal CultureInfo cultureInfo = null; /// <summary> /// Provides an Equals implementation. /// </summary> /// <param name="inputObject">Input Object.</param> /// <returns>True if both the objects are same or else returns false.</returns> public override bool Equals(object inputObject) { if (inputObject is not ObjectCommandPropertyValue objectCommandPropertyValueObject) { return false; } object baseObject = PSObject.Base(PropertyValue); object inComingbaseObjectPropertyValue = PSObject.Base(objectCommandPropertyValueObject.PropertyValue); if (baseObject is IComparable) { var success = LanguagePrimitives.TryCompare(baseObject, inComingbaseObjectPropertyValue, CaseSensitive, Culture, out int result); return success && result == 0; } if (baseObject == null && inComingbaseObjectPropertyValue == null) { return true; } if (baseObject != null && inComingbaseObjectPropertyValue != null) { return baseObject.ToString().Equals(inComingbaseObjectPropertyValue.ToString(), StringComparison.OrdinalIgnoreCase); } // One of the property values being compared is null. return false; } /// <summary> /// Provides a GetHashCode() implementation. /// </summary> /// <returns>Hashcode in the form of an integer.</returns> public override int GetHashCode() { if (PropertyValue == null) { return 0; } object baseObject = PSObject.Base(PropertyValue); if (baseObject == null) { return 0; } if (baseObject is IComparable) { return baseObject.GetHashCode(); } else { return baseObject.ToString().GetHashCode(); } } } /// <summary> /// ObjectCommandComparer class. /// </summary> internal sealed class ObjectCommandComparer : IComparer { /// <summary> /// Initializes a new instance of the <see cref="ObjectCommandComparer"/> class. /// Constructor that doesn't set any private field. /// Necessary because compareTo can compare two objects by calling /// ((ICompare)obj1).CompareTo(obj2) without using a key. /// </summary> internal ObjectCommandComparer(bool ascending, CultureInfo cultureInfo, bool caseSensitive) { _ascendingOrder = ascending; _cultureInfo = cultureInfo ?? CultureInfo.CurrentCulture; _caseSensitive = caseSensitive; } private static bool IsValueNull(object value) { object val = PSObject.Base(value); return (val == null); } internal int Compare(ObjectCommandPropertyValue first, ObjectCommandPropertyValue second) { if (first.IsExistingProperty && second.IsExistingProperty) { return Compare(first.PropertyValue, second.PropertyValue); } // if first.IsExistingProperty, !second.IsExistingProperty; otherwise the // first branch if would return. Regardless of key orders non existing property // will be considered greater than others if (first.IsExistingProperty) { return -1; } // vice versa for the previous branch if (second.IsExistingProperty) { return 1; } // both are nonexisting return 0; } /// <summary> /// Main method that will compare first and second by their keys considering case and order. /// </summary> /// <param name="first"> /// First object to extract value. /// </param> /// <param name="second"> /// Second object to extract value. /// </param> /// <returns> /// 0 if they are the same, less than 0 if first is smaller, more than 0 if first is greater. /// </returns> public int Compare(object first, object second) { // This method will never throw exceptions, two null // objects are considered the same if (IsValueNull(first) && IsValueNull(second)) { return 0; } if (first is PSObject firstMsh) { first = firstMsh.BaseObject; } if (second is PSObject secondMsh) { second = secondMsh.BaseObject; } if (!LanguagePrimitives.TryCompare(first, second, !_caseSensitive, _cultureInfo, out int result)) { // Note that this will occur if the objects do not support // IComparable. We fall back to comparing as strings. // being here means the first object doesn't support ICompare string firstString = PSObject.AsPSObject(first).ToString(); string secondString = PSObject.AsPSObject(second).ToString(); result = _cultureInfo.CompareInfo.Compare(firstString, secondString, _caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase); } return _ascendingOrder ? result : -result; } private readonly CultureInfo _cultureInfo = null; private readonly bool _ascendingOrder = true; private readonly bool _caseSensitive = false; } #endregion }