Существует ли полная ссылка реализации IEquatable?

Выполненный php в режиме линта из командной строки для проверки синтаксиса без выполнения:

php -l FILENAME

Высокоуровневые статические анализаторы включают:

, который включают анализаторы Низшего уровня:

PHP_Parser token_get_all Время выполнения анализаторы, которые более полезны для некоторых вещей из-за динамического характера PHPs, включают:

библиотеки документации phpdoc и doxygen выполняют своего рода анализ кода. Doxygen, например, может быть настроен для рендеринга хороших графиков наследования с [1 117] graphviz.

Другая опция xhprof, который подобен xdebug, но легче, делая ее подходящей для рабочих серверов. Инструмент включает основанный на PHP интерфейс.

46
задан Jader Dias 9 October 2009 в 20:36
поделиться

3 ответа

После прочтения MSDN я был уверен, что лучший пример правильной реализации находится на странице IEquatable.Equals Method . Мое единственное отклонение следующее:

public override bool Equals(Object obj)
{
   if (obj == null) return base.Equals(obj);

   if (! (obj is Person))
      return false; // Instead of throw new InvalidOperationException
   else
      return Equals(obj as Person);   
}

Для тех, кто интересуется отклонением, оно происходит из Object.Equals (Object) страницы MSDN:

Реализации Equals не должны генерировать исключения.

4
ответ дан 26 November 2019 в 20:41
поделиться

Реализация IEquatable для типа значения

Реализация IEquatable для типа значения немного отличается от ссылочного типа. Предположим, у нас есть архетип «Реализуй-свое-значение-тип», структуру сложного числа.

public struct Complex
{
    public double RealPart { get; set; }
    public double ImaginaryPart { get; set; }
}

Нашим первым шагом будет реализация IEquatable и переопределение Object.Equals и Object.GetHashCode :

public bool Equals(Complex other)
{
    // Complex is a value type, thus we don't have to check for null
    // if (other == null) return false;

    return (this.RealPart == other.RealPart)
        && (this.ImaginaryPart == other.ImaginaryPart);
}

public override bool Equals(object other)
{
    // other could be a reference type, the is operator will return false if null
    if (other is Complex)
        return this.Equals((Complex)other);
    else
        return false;
}

public override int GetHashCode()
{
    return this.RealPart.GetHashCode() ^ this.ImaginaryPart.GetHashCode();
}

С очень небольшими усилиями у нас есть правильная реализация, за исключением операторов. Добавление операторов - также тривиальный процесс:

public static bool operator ==(Complex term1, Complex term2)
{
    return term1.Equals(term2);
}

public static bool operator !=(Complex term1, Complex term2)
{
    return !term1.Equals(term2);
}

Проницательный читатель заметит, что нам, вероятно, следует реализовать IEquatable , поскольку Комплексные числа могут быть взаимозаменяемыми с базовым типом значения.

public bool Equals(double otherReal)
{
    return (this.RealPart == otherReal) && (this.ImaginaryPart == 0.0);
}

public override bool Equals(object other)
{
    // other could be a reference type, thus we check for null
    if (other == null) return base.Equals(other);

    if (other is Complex)
    {
        return this.Equals((Complex)other);
    }
    else if (other is double)
    {
        return this.Equals((double)other);
    }
    else
    {
        return false;
    }
}

Нам понадобятся четыре оператора, если мы добавим IEquatable , потому что у вас может быть Complex == double или double == Complex (и то же for operator! = ):

public static bool operator ==(Complex term1, double term2)
{
    return term1.Equals(term2);
}

public static bool operator ==(double term1, Complex term2)
{
    return term2.Equals(term1);
}

public static bool operator !=(Complex term1, double term2)
{
    return !term1.Equals(term2);
}

public static bool operator !=(double term1, Complex term2)
{
    return !term2.Equals(term1);
}

Вот и все, с минимальными усилиями у нас есть правильная и полезная реализация IEquatable для типа значения:

public struct Complex : IEquatable<Complex>, IEquatable<double>
{
}
23
ответ дан 26 November 2019 в 20:41
поделиться

Я нашел еще одну ссылку, это реализация анонимного типа .NET. Для анонимного типа со свойствами int и double я разобрал следующий код C #:

public class f__AnonymousType0
{
    // Fields
    public int A { get; }
    public double B { get; }

    // Methods
    public override bool Equals(object value)
    {
        var type = value as f__AnonymousType0;
        return (((type != null)
            && EqualityComparer<int>.Default.Equals(this.A, type.A))
            && EqualityComparer<double>.Default.Equals(this.B, type.B));
    }

    public override int GetHashCode()
    {
        int num = -1134271262;
        num = (-1521134295 * num) + EqualityComparer<int>.Default.GetHashCode(this.A);
        return ((-1521134295 * num) + EqualityComparer<double>.Default.GetHashCode(this.B);
    }

    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        builder.Append("{ A = ");
        builder.Append(this.A);
        builder.Append(", B = ");
        builder.Append(this.B);
        builder.Append(" }");
        return builder.ToString();
    }
}
4
ответ дан 26 November 2019 в 20:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: