Переопределение метода GetHashCode для треугольника с заданными сторонами

Рейтинг: 0Ответов: 1Опубликовано: 02.03.2015

Получил домашнее задание, в котором нарвался на неприятную проблему. В учебных целях нужно определить класс Triangle (треугольник). Объект класса должен всегда быть в рабочем состоянии.

В классе я определил три свойства, которые соответствуют длине каждой из его сторон. В переопределенном методе Equals я задействовал третий признак равенства треугольников, а вот с переопределением метода GetHashCode проблема. Как мне его переопределить?

class Triangle
{

    public double a
    {
        get { return _a; }
        set
        {
            if (IsTrue(value, b, c))
            {
                _a = value;
            }
            else
            {
                throw new Exception();
            }
        }
    }

    public double b
    {
        get { return _b; }
        set
        {
            if (IsTrue(a, value, c))
            {
                _b = value;
            }
            else
            {
                throw new Exception();
            }
        }
    }

    public double c
    {
        get { return _c; }
        set
        {
            if (IsTrue(a, b, value))
            {
                _c = value;
            }
            else
            {
                throw new Exception();
            }
        }
    }

    public Triangle(double a, double b, double c)
    {
        if (IsTrue(a, b, c))
        {
            _a = a;
            _b = b;
            _c = c;
        }
        else
        {
            throw new Exception();
        }
    }

    public override int GetHashCode()
    {
        /// Неправильное решение
        return a.GetHashCode() + b.GetHashCode() + c.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        var triangle = obj as Triangle;

        if (triangle != null)
        {
            /// Третий признак равенства треугольников
            return a == triangle.a && b == triangle.b && c == triangle.c;
        }

        return false;
    }

    public override string ToString()
    {
        return string.Format("Треугольник. Периметр: {0}. Площадь: {1}", Perimiter, Squere);
    }

    public double Perimiter
    {
        get { return a + b + c; }
    }

    public double HalfPerimiter
    {
        get { return Perimiter / 2; }
    }

    public double Squere
    {
        get { return Math.Sqrt(HalfPerimiter * (HalfPerimiter - a) * (HalfPerimiter - b) * (HalfPerimiter - c)); }
    }

    public static bool IsTrue(double a, double b, double c)
    {
        /// Правило треугольников
        return a < (b + c) && b < (a + c) && c < (a + b);
    }

    private double _a;

    private double _b;

    private double _c;

}

Ответы

▲ 5

Я бы посоветовал стандартное: состряпать хэш-код из хэш-кодов полей.

public override int GetHashCode()
{
    int hash_a = _a.GetHashCode(),
        hash_b = _b.GetHashCode(),
        hash_c = _c.GetHashCode();
    return ((hash_a * 13) + hash_b) * 13 + hash_c;
}

Я бы очень не рекомендовал использовать криптографические функции, в частности, MD5, так как вычисление хэшкода должно быть быстрым!